OpenSocial OpenSocial and Gadgets Specification Group
<opensocial-gadgets-api-specification-v0_9> April 15, 2009

OpenSocial Gadgets API Specification v0.9
opensocial-gadgets-api-specification-v0_9


Table of Contents


1. Notation and Conventions

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]. Domain name examples use RFC2606 [RFC2606].


2. Overview

Gadgets are web-based software components based on HTML, CSS, and JavaScript. They allow developers to easily write useful web applications that work anywhere on the web without modification. They are defined using a declarative XML syntax that is processed by a gadget server into a format that allows them to be embedded into various contexts: standalone web pages, web applications, even other gadgets. A context into which a gadget is embedded is called a gadget container. The container is responsible for managing the gadgets' layout and controls, as well as for supporting various functionality on behalf of the gadget. A gadget may be a simple widget, a reusable component, or a full-blown application, possibly utilizing or communicating with other gadgets.

A gadget and its XML are synonymous. The gadget XML contains all information needed to identify and render a web application.

Metadata. Several pieces of metadata are specified by the gadget developer in the gadget XML, such as author information, gadget title, and description. This data gives hints to the gadget container on how to identify it, in addition to providing data to gadget directories, which are databases that help users find gadgets useful for their needs

Gadget Features. A list of all gadget features that are either required for the gadget to operate, or may optionally be utilized if available. Gadget features are the primary extensibility mechanism employed by gadgets. They often direct a gadget server to make new JavaScript APIs available to rendering code, but may also manipulate the gadget's contents, for example to add extended syntax. Examples of gadget features include OpenSocial (provides gadgets with a rich set of social APIs), dynamic-height (enables gadgets to resize themselves to an appropriate height), and tabs (a UI library facilitating tabular navigation).

User Preferences. These are key/value pairs that form the basis of gadget configuration and persistence. They are most often manipulable by users of the gadget, and are persisted on behalf of a user so that the gadget has access to them across multiple rendering requests. The gadget container is typically responsible for providing their persistence for this data and an interface to edit it.

Message Bundles. Message bundles allow developers to internationalize their gadgets simply by adding name/message mappings corresponding to whatever languages the developer chooses to support. These messages may be accessed programmatically through the core JavaScript APIs provided to all gadgets, or may be statically substituted into code using simple syntax.

Content. Provides the actual HTML, CSS, and JavaScript to be rendered by the gadget. Two delivery mechanisms are supported:

Type HTML
Type HTML gadgets are the most prevalent, and are imbued with the most rich feature set. Code is provided directly in the gadget XML content section for rendering and control flow. This code simply assumes that functionality is available that has been requested from whatever gadget features were declared. In the case of optional-declared features, a simple feature-existence API can and should be consulted to ensure the capability is enabled. The code is processed by a gadget server and rendered in an IFRAME.
Type URL
Type URL gadgets only specify a base URL. A standard set of parameters are added to this URL by the gadget server, which renders the gadget in an IFRAME. The application to which the URL points must include a referenced JavaScript library using a <script> tag as it renders, to enable gadget APIs to be made available. Type URL gadgets can't take advantage of all features, notably features that manipulate HTML and JavaScript code directly. However, this gadget type has proven highly useful for turning existing web sites or applications into gadgets.

Multiple Content sections may be specified in gadget XML. Each is labeled with one or more optional view identifiers, which allow the gadget to behave or appear differently depending on the context in which it's rendered. This context is provided by the gadget container.

This document describes the gadget XML syntax and how it is processed by a compliant gadget server. In addition, it describes the core JavaScript APIs that must be made available to every gadget as it is rendered. While compliance can be attained by supporting only these core APIs, doing so severely limits a gadget server's usefulness. Gadget servers should support as many features as possible. Widely used, highly recommended features are listed at the end of this document.


3. Compliance: Gadget Server

To be gadgets-compliant, a server must be able to satisfy a Gadget Rendering Request and a JavaScript Request in the manner described. The server should be able to satisfy the Gadget Metadata Request in the manner described.

3.1 Gadget Rendering Request

The core gadget API, this translates gadget XML into content that can be rendered in a browser, typically in an IFRAME.

3.1.1 Inputs

3.1.2 Outputs

3.1.3 Process

  1. Fetch the gadget XML.
    1. This SHOULD consult a cache to minimize load on the gadget XML hosting server. The specific properties of caching are left to the implementation.
    2. The server may honor HTTP caching headers to provide developers with a way to balance the load their servers receive against the frequency with which they can reliably deploy updated content.
    3. The server SHOULD honor an IgnoreCache processing option. This causes all built-in spec caches to be ignored, fetching the spec directly from its canonical resource. This feature is very useful while developing a gadget.
      1. HTTP-based request servers SHOULD support this via a URL parameter named nocache.
      2. The server MAY implement denial-of-service protection limiting the number fetches for a spec in a given period of time, as a courtesy to developers.
  2. Parse the gadget XML.
    1. The XML MUST conform to the extended gadget spec XSD (Appendix A). This XSD represents all valid elements and attributes accepted by the legacy iGoogle gadget server (gmodules.com). However, some of these fields will be phased out. The canonical gadget spec XSD (Appendix B) the subset of attributes that must be parsed and interpreted by the server. In other words, the parser MUST NOT reject gadget specs conforming to the extended spec, yet need not interpret more than the canonical spec.
    2. On a <Content> block, the view names are represented as comma delimited strings which allows a particular <Content> block to be used on one or more surfaces. Surfaces with common view names have the inner XML of their <Content> blocks concatenated. Concatenation only occurs with exact matches of a view name on a <Content> block. Example: <Content view="Profile, Home,Home.About"/> contains Content for three named views: Profile, Home, and Home.About. Concatenation does not happen when the @href is set on a <Content> block. In this case, the set of view names on <Content> blocks with @href set to a non-null, non-empty string MUST be unique within the Gadget XML. If this is not true, the markup is invalid. A container may process gadget markup ahead of acceptance into a container's application gallery, checking for the href conditions when importing gadget XML. This validity check need not be performed at render time.
  3. Identify the Locale object corresponding to the request, and fetch messages specified by it.
    1. The <Locale> element is selected from the gadget XML by matching to the declared language and/or country. If an element matches both, use it. Otherwise select a language-only match over a country-only match. If no such match exists and an element is defined without language or country attributes defined, use it. The following assumptions are made when implementing the gadgets specification:
      1. The container MAY choose to utilize the rendered gadget's page fragment for its own purposes. Gadget developers SHOULD NOT modify this value.
      2. The behavior of relative URLs in the gadget spec is undefined. Gadget developers SHOULD output fully qualified URLs, or inject a <base> element as described in 3.1.3.
      3. Containers MUST support the <base> element as described in the HTML 4.01 specification. Containers SHOULD move <base> elements encountered in a gadget's <Content> section into the rendered gadget's <head> element, as required by the HTML 4.01 specification.
    2. Load the message bundle specified in the matched <Locale> element, if any.
      1. If the message attribute is specified, use it: load the bundle from the network using the provided URL.
      2. Otherwise use the <messagebundle> element that is a child of <Locale>, if present.
  4. Substitute "hangman variables" into supported gadget spec fields. Hangman variables are of the form __<TYPE>_<ID>__, and are replaced with string values. There are four types of hangman variables, which are defined as follows.
    1. Process message bundle into __MSG_foo__ hangman variables.
      1. The bundle MUST conform to the message bundle XSD (Appendix C).
      2. For each message named foo with value bar, hangman expansion __MSG_foo__ = bar.
    2. For each provided User Pref with key foo and value bar, hangman expansion __UP_foo__ = bar.
    3. Hangman expansion __MODULE_ID__ = <provided module ID>.
      1. HTTP-based request servers SHOULD use the URL parameter named mid for this.
    4. If a message bundle was found with language_direction = "rtl" , hangman expansions __BIDI_START_EDGE__ = "right", __BIDI_END_EDGE__ = "left", __BIDI_DIR__ = "rtl", __BIDI_REVERSE_DIR__ = "ltr". Otherwise __BIDI_START_EDGE__ = "left", __BIDI_END_EDGE__ = "right", __BIDI_DIR__ = "ltr", __BIDI_REVERSE_DIR__ = "rtl".
    5. Perform substitutions of each hangman expansion on all fields which get displayed to users. This currently includes, but is not limited to, the following fields:
      1. Module.ModulePrefs attributes, Module.Content@href, Module.Content, UserPref@display_name, UserPref@default_value, and UserPref.EnumValue@display_value.
  5. Process gadget features, specified as <Require> or <Optional> in the gadget XML.
    1. If one or more unsupported features are specified in a <Require> block, the server MUST emit a standard error message indicating that it cannot satisfy the rendering request.
      1. The message SHOULD list all requested features that could not be used because the container does not support them.
      2. The message MAY provide contact information for the gadget server administrator, along with a mechanism to request adding support for the feature.
    2. The server MUST support the following core JavaScript API, which applies to <Optional> features:
      gadgets.util.hasFeature(featureName)
      
      As indicated in the JsDoc, this method returns true if the server is able to satisfy featureName, false otherwise. Gadget developers can use this functionality to enhance their gadgets if features are available without disabling their gadget if the features are missing.
    3. The server MUST conform to the requirements specified by each requested feature in order to claim support for it. The particulars of this vary per feature, but include injecting JavaScript APIs into rendered output or the type URL-included libraries and manipulating type HTML content to support extended syntax.
  6. Output gadget content.
    1. Determine if the /Content/@href attribute is present. If so, the content for the active view is proxied and follows the rules in the section labeled Proxied Content
    2. For type HTML gadgets, the order is as follows:
      1. Standard HTML header, opening <html> tag and <body> tag. <head> information is optional. Gadgets run in browser quirks mode.
      2. Core gadgets JavaScript libraries, as specified here.
      3. Feature library initialization code, if needed.
      4. Processed gadget content, the result of steps #4 and possibly #5.
      5. A single call to gadgets.util.runOnLoadHandlers();
      6. Standard HTML closing tags.
    3. For type URL gadgets, the provided URL MUST have the following parameters added to it:
      1. up_<name>=<value> for each provided user preference.
      2. lang=<language> and country=<country>, from the provided request Locale.
      3. libs=<jsLib>, where <jsLib> is a comma-separated list of URL path fragments relative to the server's JavaScript request handler path. These fragments are added to the JS path by the type URL target to load gadget API JavaScript into its execution context.
        1. The server SHOULD consolidate all libs into a single request to minimize the number of HTTP requests made by the client browser.

3.2 Gadget Metdata Request

This API tells a gadget container how to render a gadget on a page, and gives it the container-side JavaScript it needs to support the gadget's features.

3.2.1 Context (container-side JavaScript)

t is often the case that the gadget container's support is required to satisfy gadget API requests due to the browser security model. For example, the dynamic-height feature allows a gadget to request that it be resized to fit its contents, particularly when it is in an IFRAME. Most often, the gadget is rendered on a different domain than its container, so it cannot modify the height itself. Rather, it makes an inter-domain procedure call to its container requesting that it be resized. This communication occurs through the core gadgets.rpc.* APIs, which use browser-specific techniques to pass messages between frames on different domains located in the same browser context. The container needs to be able to receive this request and respond accordingly - this is the function of the container-side JavaScript.

3.2.2 Sanitized Gadget Content Note

Rather than a Gadget Rendering Request URL, the Gadget Metadata Request API may return a version of the gadget output sanitized for security. The Caja project [Caja] provides this sanitization by rewriting HTML, CSS, and JavaScript through static analysis techniques to preclude unsafe DOM or cookie access to the gadget content, while maintaining expressiveness nearly equivalent to content running simply inside an IFRAME. This functionality is still experimental, however, so is not included in the core spec at this time.

3.2.3 Inputs

3.2.4 Outputs

3.2.5 Process

  1. Load and parse gadget XML as described in Gadget Rendering Request steps #1 and #2.
  2. Process gadget features, specified as <Require> or <Optional> in the gadget XML.
    1. Emit an error message if a required feature is not supported.
    2. Otherwise, for each requested, supported feature with container-side JavaScript, enqueue this JavaScript to return to the client.
  3. Construct URL to the corresponding Gadget Rendering Request, generated as follows:
    1. Initialize URL using a static prefix.
    2. Add parameter url=<url>, where <url> is URL of the requested gadget spec.
    3. Add user prefs parameters as described in 6.b.a (Section 3.1.3).
    4. Add locale parameters as described in 6.b.b (Section 3.1.3).
  4. Return the enqueued container-side JavaScript and Gadget Rendering Request URL.

3.3 JavaScriptRequest

In order to satisfy type URL gadgets' JavaScript library loading requests, a server MUST provide an HTTP service for retrieving core and feature-linked JavaScript.

3.3.1 Input

3.3.2 Output

3.4 Content Rewriting

Containers MAY support content rewriting. The feature supports rewriting the content of a generated gadget and allow developers to control how the behavior of the rewriter through an optional gadget feature named content-rewrite. The content-rewrite feature defines a set of rewriting operations that a container can perform on rendered and proxied content and defines rules to allow developers to control which content the rewriter can operate on.

3.4.1 Definition

The rewriter feature has the general form :

<Optional feature="content-rewrite">
    <Param name="expires">86400</Param>
    <Param name="include-url"></Param>
    <Param name="exclude-url">excluded</Param>
    <Param name="exclude-url">moreexcluded</Param>
    <Param name="minify-css">true</Param>
    <Param name="minify-js">true</Param>
    <Param name="minify-html">true</Param>
</Optional>

The parameters are defined as follows:

expires - The duration in seconds to force as minimum HTTP cache time for content fetched through the proxy via a rewritten URL. Default 86400.
include-url - Any URL which contains this parameters value as a case-insensitive substring is considered rewriteable. The literal string "*" is a special case and implies all URLs. If not specified an entry with the value "*" is assumed. This parameter can be repeated.
exclude-url - Any URL which contains this parameters value as a case-insensitive substring is excluded from rewriting. The literal string "*" implies all URLs and effectively disables all rewriting. This parameter can be repeated.
minify-css - Controls whether the container will attempt to minify css in style tags and referenced css files. Valid values are "true"|"false". Default is "true".
minify-js - Controls whether the container will attempt to minify JS in script tags and referenced JS files. Valid values are true|false. Valid values are "true"|"false". Default is "true".
minify-html - Controls whether the container will attempt to minify HTML content. Valid values are true|false. Valid values are "true"|"false". Default is "true".

Matches for "exclude-url" take precedence over matches for "include-url"

Note that the special use of "*" to denote all URLs should not be interpreted as support for GLOB or RegEx matching on strings.

Containers are free to perform additional optimizations when rewriting links including but not limited to:

Extract @import directives from style tags and convert them into link tags in the head tag of the containing HTML content.
Merge multiple CSS fetches from successive link tags into one link tag that causes the proxy to concatenate the content fetched from the individual URLs.
Merge contiguous <script src=xxx> tags into one concatenating proxy fetch.

3.4.2 Examples

Rewrite only gif images

<Optional feature="content-rewrite">
    <Param name="include-url">.gif</Param>
</Optional>

Rewrite only gif images that do not contain "animated" or "cdn"

<Optional feature="content-rewrite">
    <Param name="include-url">.gif</Param>
    <Param name="exclude-url">animated</Param>
    <Param name="exclude-url">cdn</Param>
</Optional>

Disable all rewriting

<Optional feature="content-rewrite">
    <Param name="exclude-url">*</Param>
</Optional>

3.5 Application Versioning

The presence of version strings is needed to facilitate staged or rolling updates of an application. In this way a developer can seamlessly upgrade their application from a development to a production version by moving the "current" label.

3.5.1 Processing

When processing a developer-submitted url according to the OpenSocial Gadget Specification, the container MUST determine if the content is an OpenSocial Application Manifest. Containers MUST make the determination of conformance according to XML Schema Part 1 [xsdpart1] section 4.3.2. Otherwise, containers SHOULD interpret the file as an OpenSocial Gadget Specification. Containers MAY support other document types as well. Refer to this schema (Appendix D) for valid manifest XML.

Containers MUST process the manifest using the same loose conformance requirements defined in the OpenSocial Gadget Specification.

In the event of a failure to parse the input document, containers SHOULD provide a useful error message indicating the problem with the document.

3.5.2 Selecting a Gadget Specification for Processing

After retrieving a valid manifest, containers MUST select an appropriate version of the gadget by matching either an appropriate label or version string.

When no version or label is specified on input, containers MUST process the gadget spec identified by the "current" label. Containers MAY support implicit labels when configured globally, such as in a development environment.

Among remaining specs, a container MUST first process as a group those with a matching "container" string, and finally those with no "container" specified. Within each group, each spec will be processed in the order it appears in a manifest, and a container MUST choose the first spec whose Required features it fully supports. A container MAY define any matching rule for "container", but SHOULD define a single name for its container (e.g., "myspace", "yahoo").

Manifests MUST NOT include duplicate labels or version strings. Containers SHOULD report the presence of duplicate labels or versions as an error.

Containers MUST interpret a gadget element that contains no other labels as implicitly containing the "current" label.

Containers SHOULD provide a user interface for developers to select an appropriate label to render for their application.

Containers SHOULD accept any label or version string, but MAY optionally restrict allowed characters for security purposes.


4. Proxied Content

When rendering an OpenSocial Gadget, the container MUST determine if the content for the active view is to be proxied. This is done by checking for the presence of a /Content/@href attribute.

If the attribute is present, the container MUST issue an HTTP request to the URI specified by the href attribute following the rules defined in gadgets.io.makeRequest (Section 5.2.2.3).

Attributes on the Content element map to makeRequest as follows:

Note that these attributes also apply to Preload elements.

The container MUST also add the following parameters to the URI query string:

By default, the request is sent to the remote site MUST be sent to the remote site as an HTTP GET. When the Content section includes Data Pipelining elements, the container MUST send the data to the request URI using an HTTP POST. The structure of this data will match the [JSON-RPC] format.

4.1 Processing Results

If the response to the proxied request returns a successful HTTP status code, the container MUST interpret the resulting response body according to the rules for content declared inline.

If the response to the proxied request returns an unsuccessful HTTP status code, the container SHOULD present a meaningful error message to the end user. Containers SHOULD obtain a suitable error message for display by displaying the content specified for a view named as view-name.error, where view-name matches the name of the view that the proxied request was being processed for. If an exact match can not be found, the special value default.error should be used. If default.error is not present, the container SHOULD display a generic message indicating that a problem occurred.

4.2 Caching

Containers SHOULD cache the results of the HTTP request following the recommendations of section 13 of RFC 2616 [RFC2616]. If a container does support caching of data, it MUST also support overriding HTTP caching by using the value specified for refresh_interval.

Caches SHOULD be keyed using the following:

Containers MAY cache unsuccessful HTTP responses ("negative caching"), but SHOULD NOT cache unsuccessful responses for a period longer than 5 minutes.

4.2.1 Processing Content

The container MUST normalize content bodies in a way that preserves semantic meaning in the resulting HTML output. Specifically, containers MUST preserve the structure of the document for the context the gadget will be rendered in as follows:

4.2.2 Processing XML

The container MUST resolve all URI attributes and values relative to the location of the gadget spec xml document. This DOES NOT include links inside of the body of the Content element at this point in time.


5. Core JavaScript API

5.1 gadgets

Namespace for top-level people functions.

5.1.1 Constructor

gadgets

5.1.2 Method Details

5.1.2.1 log

<static> gadgets.log(message)

Description: Log an informational message.

Parameters:

NameTypeDescription
messageObjectThe message to log

5.1.2.2 warn

<static> gadgets.warn(message)

Description: Log a warning message.

Parameters:

NameTypeDescription
messageObjectThe message to log

5.1.2.3 error

<static> gadgets.error(message)

Description: Log an error message.

Parameters:

NameTypeDescription
messageObjectThe message to log

5.1.2.4 setLogLevel

<static> gadgets.setLogLevel(logLevel)

Description: Sets the log level threshold.

Parameters:

NameTypeDescription
logLevelNumberNew log level threshold.

5.1.3 gadgets.log

Used by gadgets.setLogLevel (Section 5.1.2.4).

5.1.3.1 INFO

<static> Member of: gadgets.log

Description: Log level for informational logging.

5.1.3.2 WARN

<static> Member of: gadgets.log

Description: Log level for warning logging.

5.1.3.3 ERROR

<static> Member of: gadgets.log

Description: Log level for error logging.

5.1.3.4 NONE

<static> Member of: gadgets.log

Description: Log level for no logging.

5.2 gadgets.io

Provides remote content retrieval functions.

5.2.1 Constructor

gadgets.io

5.2.2 Method Details

5.2.2.1 encodeValues

<static> Type: {String} gadgets.io.encodeValues(fields)

Description: Converts an input object into a URL-encoded data string. (key=value&...)

Parameters:

NameTypeDescription
fieldsObjectThe post fields you wish to encode

Returns:

TypeDescription
StringThe processed post data; this includes a trailing ampersand (&)

5.2.2.2 getProxyUrl

<static> Type: {String} gadgets.io.getProxyUrl(url, opt_params)

Description: Gets the proxy version of the passed-in URL.

Parameters:

NameTypeDescription
urlStringThe URL to get the proxy URL for
opt_paramsMap<String|String>Additional optional parameters (Section 5.6) to pass to the request

Returns:

TypeDescription
StringThe proxied version of the URL

5.2.2.3 makeRequest

<static> gadgets.io.makeRequest(url, callback, opt_params)

Description: Fetches content from the provided URL and feeds that content into the callback function.

Example:

var params = {};
params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.TEXT;
gadgets.io.makeRequest(url, callback, params);
5.2.2.3.1 Signed authorization
  1. Removing any request parameters with names that begin with oauth, xoauth, or opensocial (case insensitive).
  2. Adding the following parameters to the request query string:
  3. opensocial_viewer_id
    Optional. The ID of the current viewer, which matches the getId() value on the viewer person object.
    opensocial_owner_id
    Required. The ID of the current owner, which matches the getId() value on the owner person object.
    opensocial_app_url
    Required. The URL of the application making the request. Containers may alias multiple application URLs to a single canonical application URL in the case where an application changes URLs.
    opensocial_instance_id
    Optional. An opaque identifier used to distinguish between multiple instances of the same application in a single container. If a container does not allow multiple instances of the same application to coexist, this parameter may be omitted. The combination of opensocial_app_url and opensocial_instance_id uniquely identify an instance of an application in a container.
    opensocial_app_id
    Optional. An opaque identifier for the application, unique to a particular container. Containers that wish to maintain backwards compatibility with the opensocial-0.7 specification may include this parameter.
    xoauth_public_key
    Optional. An opaque identifier for the public key used to sign the request. This parameter may be omitted by containers that do not use public keys to sign requests, or if the container arranges other means of key distribution with the target of the request.
  4. Signing the resulting request according to section 9 of the OAuth specification.
5.2.2.3.2 management for gadgets.io.AuthorizationType.SIGNED

If a container uses public keys to sign requests, the container may choose to use either self-signed certificates or certificates signed by a well-known certificate authority. If a container does not distribute its OAuth signing key over HTTPS, it should use a certificate signed by a well-known certificate authority.

The commonName attribute of the certificate should match the hostname of the container server, and should also match the value of the oauth_consumer_key parameter specified in the request.

The container should make its public key available for download at a well-known location. The location https://[container-hostname]/opensocial/certificates/xoauth_public_keyvalue is recommended.

Recipients of signed requests must verify that the signature on the request is correct, and that the timestamp on the request is within a reasonable time window. A time window of 5 minutes before and after the current time is recommended.

Recipients of signed requests may use the oauth_consumer_key and xoauth_public_key parameters to automatically detect when a container deploys new certificates. If the container deploys certificates at a well-known location, the recipient may automatically download the new certificate. Recipients that automatically download new certificates should cache the resulting certificates.

If a container's certificate is not downloaded from https://[container-hostname], the recipient should verify that the certificate is signed by a well-known certificate authority before trusting the certificate.

5.2.2.3.3 OAuth authorization

If opt_params[gadgets.io.RequestParameters.AUTHORIZATION] is set to gadgets.io.AuthorizationType.OAUTH, the container needs to use OAuth to gain access to the resource specified in the request. This may require that the gadget obtain the user's content by directing the user to the service provider to gain access.

5.2.2.3.4 Additional parameters

The following additional parameters may be specified in opt_params:

gadgets.io.RequestParameters.OAUTH_SERVICE_NAME
The nickname the gadget uses to refer to the OAuth <Service> element from its XML spec. If unspecified, defaults to "".
gadgets.io.RequestParameters.OAUTH_TOKEN_NAME
The nickname the gadget uses to refer to an OAuth token granting access to a particular resources. If unspecified, defaults to "". Gadgets can use multiple token names if they have access to multiple resources from the same service provider. For example, a gadget with access to a contact list and a calendar might use a token name of "contacts" to use the contact list token, and a contact list of "calendar" to use the calendar token.
gadgets.io.RequestParameters.OAUTH_REQUEST_TOKEN
A service provider may be able to automatically provision a gadget with a request token that is preapproved for access to a resource. The gadget can use that token with the OAUTH_REQUEST_TOKEN parameter. This parameter is optional.
gadgets.io.RequestParameters.OAUTH_REQUEST_TOKEN_SECRET
The secret corresponding to a preapproved request token. This parameter is optional.

If OAuth is used, the container should execute the OAuth protocol on behalf of the gadget. If the gadget has not registered a consumer key for use with this service provider, the container may choose to use a default RSA signing key corresponding to a well-known certificate to sign requests. If the container uses a default consumer key, it will include an additional OAuth parameter xoauth_app_url that identifies the gadget making the request.

5.2.2.3.5 The callback parameter

The makeRequest() callback parameter is passed a javascript object with several OAuth-specific fields in addition to the normal values returned by makeRequest():

"oauthApprovalUrl"
If this value is specified, the user needs to visit an external page to approve the gadget's request to access data. Use of a pop-up window to direct the user to the external page is recommended. Once the user has approved access, the gadget can repeat the makeRequest call to retrieve the data.
"oauthError"
If this value is specified, it indicates an OAuth-related error occurred. The value will be one of a set of string constants that can be used for programmatically detecting errors. The constants are undefined for opensocial-0.8, but implementers should attempt to agree on a set of useful constant values for standardization in opensocial-0.9.
"oauthErrorText"
If this value is specified, it indicates an OAuth-related error occurred. The value is free-form text that can be used to provide debugging information for gadget developers.
5.2.2.3.6 Parameters

NameTypeDescription
urlStringThe URL where the content is located
callbackFunctionThe function to call with the data from the URL once it is fetched. The callback function will not be called until after the existing callstack has completed execution.
opt_paramsMap.<gadgets.io.RequestParameters|Object>Additional request parameters (Section 5.7) or proxy request parameters (Section 5.6)

5.3 gadgets.io.AuthorizationType

Used by RequestParameters (Section 5.7).

5.3.1 Constructor

gadgets.io.AuthorizationType

5.3.2 Field Details

5.3.2.1 NONE

<static> Member of: gadgets.io.AuthorizationType.NONE

Description: No authorization. This field may be used interchangeably with the string 'NONE'.

5.3.2.2 OAUTH

<static> Member of: gadgets.io.AuthorizationType.OAUTH

Description: The container will use OAuth for authentication. This field may be used interchangeably with the string 'OAUTH'.

5.3.2.3 SIGNED

<static> Member of: gadgets.io.AuthorizationType.SIGNED

Description: The request will be signed by the container. This field may be used interchangeably with the string 'SIGNED'.

5.4 gadgets.io.ContentType

Used by RequestParameters (Section 5.7).

5.4.1 Constructor

gadgets.io.ContentType

5.4.2 Field Details

5.4.2.1 DOM

<static> Member of: gadgets.io.ContentType.DOM

Description: Returns a DOM object; used for fetching XML. This field may be used interchangeably with the string 'DOM'.

5.4.2.2 FEED

<static> Member of: gadgets.io.ContentType.FEED

Description: Returns a JSON representation of an RSS or Atom feed. This field may be used interchangeably with the string 'FEED'.

5.4.2.3 JSON

<static> Member of: gadgets.io.ContentType.JSON

Description: Returns a JSON object. This field may be used interchangeably with the string 'JSON'.

5.4.2.4 TEXT

<static> Member of: gadgets.io.ContentType.TEXT

Description: Returns text; used for fetching HTML. This field may be used interchangeably with the string 'TEXT'.

5.5 gadgets.io.MethodType

Defines values for RequestParameters.METHOD (Section 5.7.2.5).

5.5.1 Constructor

gadgets.io.MethodType

5.5.2 Field Details

5.5.2.1 DELETE

<static> Member of: gadgets.io.MethodType.DELETE

Description: Container support for this method type is OPTIONAL. This field may be used interchangeably with the string 'DELETE'.

5.5.2.2 GET

<static> Member of: gadgets.io.MethodType.GET

Description: The default type. This field may be used interchangeably with the string 'GET'.

5.5.2.3 HEAD

<static> Member of: gadgets.io.MethodType.HEAD

Description: Container support for this method type is OPTIONAL. This field may be used interchangeably with the string 'HEAD'.

5.5.2.4 POST

<static> Member of: gadgets.io.MethodType.POST

Description: Container support for this method type is OPTIONAL. This field may be used interchangeably with the string 'POST'.

5.5.2.5 PUT

<static> Member of: gadgets.io.MethodType.PUT

Description: Container support for this method type is OPTIONAL. This field may be used interchangeably with the string 'PUT'.

5.6 gadgets.io.ProxyUrlRequestParameters

Used by gadgets.io.getProxyUrl() (Section 5.2.2.2) method.

5.6.1 Constructor

gadgets.io.ProxyUrlRequestParameters

5.6.2 Field Details

5.6.2.1 REFRESH_INTERVAL

<static> Member of: gadgets.io.ProxyUrlRequestParameters.REFRESH_INTERVAL

Description: Explicitly sets the lifespan of cached content. The Refresh Interval is the number of seconds the container should cache the given response. By default, the HTTP caching headers will be respected for fetched content. If the refresh interval is set, this value will take precedence over any HTTP cache headers. If this value is not set and there are no HTTP caching headers specified, this value will default to 3600 (one hour). Note that Signed requests and objects with POST_DATA present will generally not be cached. This field may be used interchangeably with the string 'REFRESH_INTERVAL'.

5.7 gadgets.io.RequestParameters

Used by the gadgets.io.makeRequest() (Section 5.2.2.3) method.

5.7.1 Constructor

gadgets.io.RequestParameters

5.7.2 Field Details

5.7.2.1 AUTHORIZATION

<static> Member of: gadgets.io.RequestParameters.AUTHORIZATION

Description: The type of authentication to use when fetching the content; defaults to AuthorizationType.NONE. Specified as an AuthorizationType (Section 5.3). This field may be used interchangeably with the string 'AUTHORIZATION'.

5.7.2.2 CONTENT_TYPE

<static> Member of: gadgets.io.RequestParameters.CONTENT_TYPE

Description: The type of content that lives at the URL; defaults to ContentType.TEXT. Specified as a ContentType (Section 5.4). This field may be used interchangeably with the string 'CONTENT_TYPE'.

5.7.2.3 GET_SUMMARIES

<static> Member of: gadgets.io.RequestParameters.GET_SUMMARIES

Description: If the content is a feed, whether to fetch summaries for that feed; defaults to false. Specified as a Boolean. This field may be used interchangeably with the string 'GET_SUMMARIES'.

5.7.2.4 HEADERS

<static> Member of: gadgets.io.RequestParameters.HEADERS

Description: The HTTP headers to send to the URL; defaults to null. Specified as a Map.<String,String>. This field may be used interchangeably with the string 'HEADERS'.

5.7.2.5 METHOD

<static> Member of: gadgets.io.RequestParameters.METHOD

Description: The method to use when fetching content from the URL; defaults to MethodType.GET (Section 5.5.2.2). Valid values are specified by MethodType (Section 5.5). This field may be used interchangeably with the string 'METHOD'.

5.7.2.6 NUM_ENTRIES

<static> Member of: gadgets.io.RequestParameters.NUM_ENTRIES

Description: If the content is a feed, the number of entries to fetch; defaults to 3. Specified as a Number. This field may be used interchangeably with the string 'NUM_ENTRIES'.

5.7.2.7 POST_DATA

<static> Member of: gadgets.io.RequestParameters.POST_DATA

Description: The data to send to the URL using the POST method; defaults to null. Specified as a String. This field may be used interchangeably with the string 'POST_DATA'.

5.7.2.8 REFRESH_INTERVAL

<static> Member of: gadgets.io.RequestParameters.REFRESH_INTERVAL

Description: Explicitly sets the lifespan of cached content. The Refresh Interval is the number of seconds the container should cache the given response. By default, the HTTP caching headers will be respected for fetched content. If the refresh interval is set, this value will take precedence over any HTTP cache headers. If this value is not set and there are no HTTP caching headers specified, this value will default to 3600 (one hour). Note that Signed requests and objects with POST_DATA present will generally not be cached. This field may be used interchangeably with the string 'REFRESH_INTERVAL'.

5.8 gadgets.json

Provides operations for translating objects to and from JSON.

5.8.1 Constructor

gadgets.json

5.8.2 Method Details

5.8.2.1 parse

<static> Type: {Object} gadgets.json.parse(text)

Description: Parses a JSON string, producing a JavaScript value.

Parameters:

NameTypeDescription
textStringThe string to transform into an object; usually the result of a previous stringify call

Returns:

TypeDescription
ObjectThe object parsed from the passed in text; false if an error occurred

5.8.2.2 stringify

<static> Type: {String} gadgets.json.stringify(v)

Description: Converts a JavaScript value to a JSON string.

Parameters:

NameTypeDescription
vObjectThe object to convert

Returns:

TypeDescription
StringThe JSON equivalent

5.9 gadgets.Prefs

Provides access to user preferences, module dimensions, and messages. Clients can access their preferences by constructing an instance of gadgets.Prefs and passing in their module ID. Example:

var prefs = new gadgets.Prefs();
var name = prefs.getString("name");
var lang = prefs.getLang();

5.9.1 Constructor

gadgets.Prefs(opt_moduleId)

Creates a new Prefs object.

Parameters:

NameTypeDescription
opt_moduleIdString | NumberAn optional parameter specifying the module ID to create prefs for; if not provided, the default module ID is used

5.9.2 Method Details

5.9.2.1 getArray

Type: {Array.<String>} getArray(key)

Description: Retrieves a preference as an array. UserPref values that were not declared as lists are treated as one-element arrays.

Parameters:

NameTypeDescription
keyStringThe preference to fetch

Returns:

TypeDescription
Array.<String>The preference; if not set, an empty array

5.9.2.2 getBool

Type: {Boolean} getBool(key)

Description: Retrieves a preference as a boolean.

Parameters:

NameTypeDescription
keyStringThe preference to fetch

Returns:

TypeDescription
BooleanThe preference; if not set, false

5.9.2.3 getCountry

Type: {String} getCountry()

Description: Gets the current country, returned as ISO 3166-1 alpha-2 code.

Returns:

TypeDescription
StringThe country for this module instance

5.9.2.4 getFloat

Type: {Number} getFloat(key)

Description: Retrieves a preference as a floating-point value.

Parameters:

NameTypeDescription
keyStringThe preference to fetch

Returns:

TypeDescription
NumberThe preference; if not set, 0

5.9.2.5 getInt

Type: {Number} getInt(key)

Description: Retrieves a preference as an integer.

Parameters:

NameTypeDescription
keyStringThe preference to fetch

Returns:

TypeDescription
NumberThe preference; if not set, 0

5.9.2.6 getLang

Type: {String} getLang()

Description: Gets the current language the gadget should use when rendering, returned as a ISO 639-1 language code.

Returns:

TypeDescription
StringThe language for this module instance

5.9.2.7 getModuleId

Type: {String | Number} getModuleId()

Description: Gets the module ID for the current instance.

Returns:

TypeDescription
String | NumberThe module ID for this module instance

5.9.2.8 getMsg

Type: {String} getMsg(key)

Description: Fetches an unformatted message.

Parameters:

NameTypeDescription
keyStringThe message to fetch

Returns:

TypeDescription
StringThe message

5.9.2.9 getString

Type: {String} getString(key)

Description: Retrieves a preference as a string.

Parameters:

NameTypeDescription
keyStringThe preference to fetch

Returns:

TypeDescription
StringThe preference; if not set, an empty string

5.9.2.10 set

set(key, val)

Description: Stores a preference. To use this call, the gadget must require the feature setprefs.

Note: If the gadget needs to store an Array it should use setArray instead of this call.

Parameters:

NameTypeDescription
keyStringThe pref to store
valObjectThe values to store

5.9.2.11 setArray

setArray(key, val)

Description: Stores an array preference. To use this call, the gadget must require the feature setprefs.

Parameters:

NameTypeDescription
keyStringThe pref to store
valArrayThe values to store

5.10 gadgets.util

Provides general-purpose utility functions.

5.10.1 Constructor

gadgets.util

5.10.2 Method Details

5.10.2.1 escapeString

<static> Type: {String} gadgets.util.escapeString(str)

Description: Escapes the input using HTML entities to make it safer. The following characters are affected:

Parameters:

NameTypeDescription
strStringThe string to escape

Returns:

TypeDescription
StringThe escaped string

5.10.2.2 getFeatureParameters

<static> Type: {Object} gadgets.util.getFeatureParameters(feature)

Description: Returns the value of parameters for this feature. A gadget specifies parameters using the <Param> subelement of the <Requires> or <Optional> element.

Parameters:

NameTypeDescription
featureStringThe feature to get parameters for

Returns:

TypeDescription
ObjectThe parameters for the given feature, or null

5.10.2.3 hasFeature

<static> Type: {Boolean} gadgets.util.hasFeature(feature)

Description: Returns whether the specified feature is supported.

Parameters:

NameTypeDescription
featureStringThe feature to test for

Returns:

TypeDescription
BooleanTrue if the feature is supported

5.10.2.4 registerOnLoadHandler

<static> gadgets.util.registerOnLoadHandler(callback)

Description: Registers an onload handler; a function that's executed when the gadget loads. Multiple handlers can be registered, and all will be invoked in the same order that they were registered.

Parameters:

NameTypeDescription
callbackFunctionThe handler to run. The callback function will not be called until after the existing callstack has completed execution.

5.10.2.5 sanitizeHtml

<static> Type: {String} gadgets.util.sanitizeHtml(text)

Description: Sanitizes a text string. The returned value is safe to assign to innerHTML. The returned value may include HTML tags. If plain text is desired, use gadgets.util.escapeString instead.

Parameters:

NameTypeDescription
textStringarbitrary text string

Returns:

TypeDescription
Stringa sanitized version that may include HTML tags, but will not execute script.

5.10.2.6 unescapeString

<static> Type: {String} gadgets.util.unescapeString(str)

Description: Reverses escapeString

Parameters:

NameTypeDescription
strStringThe string to unescape.

Returns:

TypeDescription
StringThe unescaped string

5.11 gadgets.views

Provides operations for dealing with views.

See also: gadgets.views.View (Section 5.12)

5.11.1 Constructor

gadgets.views

5.11.2 Method Details

5.11.2.1 bind

<static> Type: {String} gadgets.views.bind(urlTemplate, environment)

Description: Binds a URL template with variables in the passed environment to produce a URL string.

See also: View.getUrlTemplate() (Section 5.12.2.3)

Parameters:

NameTypeDescription
urlTemplateA url template for a container view
environmentA set of named variables (for example, [[]OWNER | PATH | PARAMS | NAME]) of type string.

Returns:

TypeDescription
StringA URL string

5.11.2.2 getCurrentView

<static> Type: { gadgets.views.View (Section 5.12) } gadgets.views.getCurrentView()

Description: Returns the current view.

Returns:

TypeDescription
gadgets.views.View (Section 5.12) The current view

5.11.2.3 getParams

<static> Type: {Map.<String|String>} gadgets.views.getParams()

Description: Returns the parameters passed into this gadget for this view. Does not include all URL parameters, only the ones passed into gadgets.views.requestNavigateTo.

Returns:

TypeDescription
Map.<String|String>The parameter map

5.11.2.4 getSupportedViews

<static> Type: {Map<gadgets.views.ViewType | String|gadgets.views.View>} gadgets.views.getSupportedViews()

Description: Returns a map of all the supported views. Keys each gadgets.view.View by its name. This function only returns the primary views and does not return any secondary views. Example: if the markup indicates a set of views named Canvas.About, Profile.About, Home.About, Canvas.Help the returned views will only be Canvas, Profile, Home.

Returns:

TypeDescription
Map<gadgets.views.ViewType | String|gadgets.views.View>All supported views, keyed by their name attribute.

5.11.2.5 requestNavigateTo

<static> gadgets.views.requestNavigateTo(|, |, opt_ownerId)

Description: Attempts to navigate to this gadget in a different view. If the container supports parameter passing it will pass the optional parameters along to the gadget in the new view. This also allows for navigation to named views on the current surface. Views are composed of names that are [Surface](.[Secondary])?. The canonical Surface names are Canvas, Profile, Home. The Secondary names are user defined. When navigating from [Surface].valueX to [Surface].valueY, the container can stay on the same Surface but will show the appropriate <Content> sections whose View is [Surface].valueY. When navigating from SurfaceA.[Secondary] to SurfaceB.[Secondary], the container will switch to the SurfaceB surface and show the appropriate <Content> sections whose View is SurfaceB.[Secondary].In no cases must the .[Secondary] item ever be declared.

Parameters:

NameTypeDescription
|gadgets.views.View{string} view If set to a string, the name of the view to navigate to. If set to a View, the View object to navigate to. Passing a View has been deprecated.
|Map.<String|String>{string} opt_params If the value is an object, it represents parameters to pass to the gadget after it has been navigated to on the surface. If the view navigated to contains an href and opt_params is a string, the value in opt_params is treated as a relative path that must be resolved relative to the href of the referenced view according to RFC 3986. If opt_params is a string all query parameters including query parameters encoded in a fragment are available in the receiving view using gadgets.views.getParams()
opt_ownerIdStringThe ID of the owner of the page to navigate to; defaults to the current owner

5.12 gadgets.views.View

Base interface for all view objects.

5.12.1 Constructor

gadgets.views.View()

NOTE: CONSTRUCTOR SHOULD NOT BE DOCUMENTED

5.12.2 Method Details

5.12.2.1 bind

Type: {String} bind(environment)

Description: Binds the view's URL template with variables in the passed environment to produce a URL string.

See also: getUrlTemplate() (Section 5.12.2.3)

Parameters:

NameTypeDescription
environmentA set of named variables (for example, [[]OWNER | PATH | PARAMS | NAME]) of type string.

Returns:

TypeDescription
StringA URL string

5.12.2.2 getName

Type: { gadgets.views.ViewType (Section 5.13) | String} getName()

Description: Returns the name of this view.

Returns:

TypeDescription
gadgets.views.ViewType (Section 5.13) | StringThe view name, usually specified as a gadgets.views.ViewType

5.12.2.3 getUrlTemplate

Type: {String} getUrlTemplate()

Description: Returns a string URI template conforming to the IETF spec draft with variables for substitution.

Four variables are supported:

name
The name or ID of the application
owner
The ID of the owner of the page
path
An array of path steps
`
params
Associative array or array[[]param1,value1,param2,value2,...]

Example

Here are two valid URL template strings:

http://container.com/{-list|/|name,owner,path}?{-join|&|params}
http://container.com/apps/{name}/{owner}{-prefix|/|path}{-opt|?os_|params}{-join|&os_|params}

Here are some parameters:

{
    name : 'Wilma',
    owner : 'Betty',
    path : ['dino','car'],
    params : { a : 'Barney', b : 'Fred'}          
}

With those parameters, the two example URL template strings resolve to the following URLs:

http://container.com/Wilma/Betty/dino/car?a=Barney&b=Fred
http://container.com/apps/Wilma/Betty/dino/car?os_a=Barney&os_b=Fred

See also: bind() (Section 5.12.2.1)

Returns:

TypeDescription
StringA template that can be used to construct URLs that navigate to this view

5.12.2.4 isOnlyVisibleGadget

Type: {boolean} isOnlyVisibleGadget()

Description: Returns true if the gadget is the only visible gadget in this view. On a canvas page or in maximize mode this is most likely true; on a profile page or in dashboard mode, it is most likely false.

Returns:

TypeDescription
booleanTrue if the gadget is the only visible gadget; otherwise, false

5.13 gadgets.views.ViewType

Used by View (Section 5.12) s.

5.13.1 Constructor

gadgets.views.ViewType

5.13.2 Field Details

5.13.2.1 CANVAS

<static> Member of: gadgets.views.ViewType.CANVAS

Description: A view where the gadget is displayed in a very large mode. It is typically the main content on the page. The viewer is not always the same as the owner. This field may be used interchangeably with the string 'CANVAS'.

5.13.2.2 HOME

<static> Member of: gadgets.views.ViewType.HOME

Description: A view where the gadget is displayed in a small area usually on a page with other gadgets. Typically the viewer is the same as the owner. This field may be used interchangeably with the string 'HOME'.

5.13.2.3 PREVIEW

<static> Member of: gadgets.views.ViewType.PREVIEW

Description: A demo view of the gadget. In this view the owner and viewer are not known. This field may be used interchangeably with the string 'PREVIEW'.

5.13.2.4 PROFILE

<static> Member of: gadgets.views.ViewType.PROFILE

Description: A view where the gadget is displayed in a small area usually on a page with other gadgets. The viewer is not always the same as the owner. This field may be used interchangeably with the string 'PROFILE'.


6. Highly Recommended Features

6.1 gadgets.flash

Embeds Flash content in gadgets.

6.1.1 Constructor

gadgets.flash

6.1.2 Method Details

6.1.2.1 embedCachedFlash

<static> Type: {Boolean} gadgets.flash.embedCachedFlash()

Description: Injects a cached Flash file into the DOM tree. Accepts the same parameters as gadgets.flash.embedFlash does.

Returns:

TypeDescription
BooleanWhether the function call completes successfully

6.1.2.2 embedFlash

<static> Type: {Boolean} gadgets.flash.embedFlash(swfUrl, swfContainer, swfVersion, opt_params)

Description: Injects a Flash file into the DOM tree.

Parameters:

NameTypeDescription
swfUrlStringSWF URL
swfContainerString | ObjectThe ID or object reference of an existing HTML container element
swfVersionNumberMinimum Flash Player version required
opt_paramsObjectAn optional object that may contain any valid HTML parameter; all attributes will be passed through to the Flash movie on creation

Returns:

TypeDescription
BooleanWhether the function call completes successfully

6.1.2.3 getMajorVersion

<static> Type: {Number} gadgets.flash.getMajorVersion()

Description: Detects Flash Player and its major version.

Returns:

TypeDescription
NumberThe major version of Flash Player or 0 if Flash is not supported

6.2 gadgets.MiniMessage

MiniMessage class, used to create messages that will appear to the user within the gadget. Typical use cases:

6.2.1 Constructor

gadgets.MiniMessage(opt_moduleId, opt_container)

Creates a MiniMessage.

Parameters:

NameTypeDescription
opt_moduleIdStringOptional module ID
opt_containerHTMLElementOptional HTML container element where mini-messages will appear

6.2.2 Method Details

6.2.2.1 createDismissibleMessage

Type: {HTMLElement} createDismissibleMessage(message, opt_callback)

Description: Creates a dismissible message with an [[]x] icon that allows users to dismiss the message. When the message is dismissed, it is removed from the DOM and the optional callback function, if defined, is called.

Parameters:

NameTypeDescription
messageString | ObjectThe message as an HTML string or DOM element
opt_callbackFunctionOptional callback function to be called when the message is dismissed. The callback function will not be called until after the existing callstack has completed execution.

Returns:

TypeDescription
HTMLElementHTML element of the created message

6.2.2.2 createStaticMessage

Type: {HTMLElement} createStaticMessage(message)

Description: Creates a static message that can only be dismissed programmatically (by calling dismissMessage()).

Parameters:

NameTypeDescription
messageString | ObjectThe message as an HTML string or DOM element

Returns:

TypeDescription
HTMLElementHTML element of the created message

6.2.2.3 createTimerMessage

Type: {HTMLElement} createTimerMessage(message, seconds, opt_callback)

Description: Creates a message that displays for the specified number of seconds. When the timer expires, the message is dismissed and the optional callback function is executed.

Parameters:

NameTypeDescription
messageString | ObjectThe message as an HTML string or DOM element
secondsnumberNumber of seconds to wait before dismissing the message
opt_callbackFunctionOptional callback function to be called when the message is dismissed. The callback function will not be called until after the existing callstack has completed execution.

Returns:

TypeDescription
HTMLElementHTML element of the created message

6.2.2.4 dismissMessage

dismissMessage(message)

Description: Dismisses the specified message.

Parameters:

NameTypeDescription
messageHTMLElementHTML element of the message to remove

6.3 gadgets.oauth.Popup

OAuth popup window manager.

Expected usage:

  1. Gadget attempts to fetch OAuth data for the user and discovers that approval is needed. The gadget creates two new UI elements: The "personalization done" button may be unnecessary. The popup window manager will attempt to detect when the window closes. However, the "personalization done" button should still be displayed to handle cases where the popup manager is unable to detect that a window has closed. This allows the user to signal approval manually.
  2. Gadget creates a popup object and associates event handlers with the UI elements:
    // Called when the user opens the popup window.
    var onOpen = function() {
      $("personalizeDone").style.display = "block"
    }
    // Called when the user closes the popup window.
    var onClose = function() {
      $("personalizeDone").style.display = "none"
      fetchData();
    }
    var popup = new gadgets.oauth.Popup(
        response.oauthApprovalUrl,
        "height=300,width=200",
        onOpen,
        onClose
    );
    personalizeButton.onclick = popup.createOpenerOnClick();
    personalizeDoneButton.onclick = popup.createApprovedOnClick();
    
  3. When the user clicks the personalization button/link, a window is opened to the approval URL. The onOpen function is called to notify the gadget that the window was opened.
  4. When the window is closed, the popup manager calls the onClose function and the gadget attempts to fetch the user's data.

6.3.1 Constructor

gadgets.oauth.Popup(destination, windowOptions, openCallback, closeCallback)

Description: used to create a new OAuth popup window manager.

Parameters:

NameTypeDescription
destinationStringTarget URL for the popup window.
windowOptionsStringOptions for window.open, used to specify look and feel of the window.
openCallbackFunctionFunction to call when the window is opened.
closeCallbackFunctionFunction to call when the window is closed.

6.3.2 Method Details

6.3.2.1 createOpenerOnClick

Type: {Function} createOpenerOnClick()

Returns:

TypeDescription
Functionan onclick handler for the "open the approval window" link.

6.3.2.2 createApprovedOnClick

Type: {Function} createApprovedOnClick()

Returns:

TypeDescription
Functionan onclick handler for the "I've approved" link. This may not ever be called. If we successfully detect that the window was closed, this link is unnecessary.

6.4 gadgets.rpc

Provides operations for making remote procedure calls for gadget-to-container, container-to-gadget, and gadget-to-gadget communication.

6.4.1 Constructor

gadgets.rpc

6.4.2 Method Details

6.4.2.1 call

<static> gadgets.rpc.call(targetId, serviceName, callback, var_args)

Description: Calls an RPC service.

Parameters:

NameTypeDescription
targetIdStringID of the RPC service provider; empty if calling the parent container
serviceNameStringService name to call
callbackFunction|nullCallback function (if any) to process the return value of the RPC request. The callback function will not be called until after the existing callstack has completed execution.
var_args*Parameters for the RPC request

6.4.2.2 register

<static> gadgets.rpc.register(serviceName, handler)

Description: Registers an RPC service.

Parameters:

NameTypeDescription
serviceNameStringService name to register
handlerFunctionService handler

6.4.2.3 registerDefault

<static> gadgets.rpc.registerDefault(handler)

Description: Registers a default service handler to process all unknown remote procedure calls, which fail silently by default.

Parameters:

NameTypeDescription
handlerFunctionService handler

6.4.2.4 unregister

<static> gadgets.rpc.unregister(serviceName)

Description: Unregisters an RPC service.

Parameters:

NameTypeDescription
serviceNameStringService name to unregister

6.4.2.5 unregisterDefault

<static> gadgets.rpc.unregisterDefault()

Description: Unregisters the default service handler. Future unknown remote procedure calls will fail silently.

6.5 gadgets.skins

Provides operations for getting display information about the currently shown skin.

6.5.1 Constructor

gadgets.skins

6.5.2 Method Details

6.5.2.1 getProperty

<static> Type: {String} gadgets.skins.getProperty(propertyKey)

Description: Fetches the display property mapped to the given key.

Parameters:

NameTypeDescription
propertyKeyStringThe key to get data for; keys are defined in gadgets.skins.Property (Section 6.6)

Returns:

TypeDescription
StringThe data

6.6 gadgets.skins.Property

All of the display values that can be fetched and used in the gadgets UI. These are the supported keys for the gadgets.skins.getProperty() (Section 6.5.2.1) method.

6.6.1 Constructor

gadgets.skins.Property

6.6.2 Field Details

6.6.2.1 ANCHOR_COLOR

<static> Member of: gadgets.skins.Property.ANCHOR_COLOR

Description: The color that anchor tags should use. This field may be used interchangeably with the string 'ANCHOR_COLOR'.

6.6.2.2 BG_COLOR

<static> Member of: gadgets.skins.Property.BG_COLOR

Description: The color of the background of the gadget. This field may be used interchangeably with the string 'BG_COLOR'.

6.6.2.3 BG_IMAGE

<static> Member of: gadgets.skins.Property.BG_IMAGE

Description: An image to use in the background of the gadget. This field may be used interchangeably with the string 'BG_IMAGE'.

6.6.2.4 FONT_COLOR

<static> Member of: gadgets.skins.Property.FONT_COLOR

Description: The color in which the main font should be rendered. This field may be used interchangeably with the string 'FONT_COLOR'.

6.7 gadgets.Tab

Tab class for gadgets. You create tabs using the TabSet addTab() method. To get Tab objects, use the TabSet getSelectedTab() or getTabs() methods.

See also: TabSet (Section 6.8)

6.7.1 Constructor

gadgets.Tab()

NOTE: CONSTRUCTOR SHOULD NOT BE DOCUMENTED

6.7.2 Method Details

6.7.2.1 getCallback

Type: {Function} getCallback()

Description: Returns the callback function that is executed when the tab is selected.

Returns:

TypeDescription
FunctionThe callback function of the tab

6.7.2.2 getContentContainer

Type: {HTMLElement} getContentContainer()

Description: Returns the HTML element where the tab content is rendered.

Returns:

TypeDescription
HTMLElementThe HTML element of the content container

6.7.2.3 getIndex

Type: {Number} getIndex()

Description: Returns the tab's index.

Returns:

TypeDescription
NumberThe tab's index

6.7.2.4 getName

Type: {String} getName()

Description: Returns the label of the tab as a string (may contain HTML).

Returns:

TypeDescription
StringThe label of the tab

6.7.2.5 getNameContainer

Type: {HTMLElement} getNameContainer()

Description: Returns the HTML element that contains the tab's label.

Returns:

TypeDescription
HTMLElementThe HTML element of the tab's label

6.8 gadgets.TabSet

A class gadgets can use to make tabs.

6.8.1 Constructor

gadgets.TabSet(opt_moduleId, opt_defaultTab, opt_container)

Creates a new TabSet object

Parameters:

NameTypeDescription
opt_moduleIdStringOptional suffix for the ID of tab container
opt_defaultTabStringOptional tab name that specifies the name of of the tab that is selected after initialization; if this parameter is omitted, the first tab is selected by default
opt_containerHTMLElementThe HTML element to contain the tabs; if omitted, a new div element is created and inserted at the very top

6.8.2 Method Details

6.8.2.1 addTab

Type: {String} addTab(tabName, opt_params)

Description: Adds a new tab based on the name-value pairs specified in opt_params. The following properties are supported in opt_params:

contentContainer
An existing HTML element to be used as the tab content container. If omitted, the tabs library creates one.
callback
A callback function to be executed when the tab is selected. The callback function will not be called until after the existing callstack has completed execution.
tooltip
A tooltip description that pops up when user moves the mouse cursor over the tab.
index
The index at which to insert the tab. If omitted, the new tab is appended to the end.

Parameters:

NameTypeDescription
tabNameStringLabel of the tab to create
opt_paramsObjectOptional parameter object

Returns:

TypeDescription
StringDOM id of the tab container

6.8.2.2 alignTabs

alignTabs(align, opt_offset)

Description: Sets the alignment of tabs. Tabs are center-aligned by default.

Parameters:

NameTypeDescription
alignString'left', 'center', or 'right'
opt_offsetNumberOptional parameter to set the number of pixels to offset tabs from the left or right edge; the default value is 3px

6.8.2.3 displayTabs

displayTabs(display)

Description: Shows or hides tabs and all associated content.

Parameters:

NameTypeDescription
displayBooleanTrue to show tabs; false to hide tabs

6.8.2.4 getHeaderContainer

Type: {HTMLElement} getHeaderContainer()

Description: Returns the tab headers container element.

Returns:

TypeDescription
HTMLElementThe tab headers container element

6.8.2.5 getSelectedTab

Type: { gadgets.Tab (Section 6.7) } getSelectedTab()

Description: Returns the currently selected tab object.

Returns:

TypeDescription
gadgets.Tab (Section 6.7) The currently selected tab object

6.8.2.6 getTabs

Type: {Array.<gadgets.Tab>} getTabs()

Description: Returns an array of all existing tab objects.

Returns:

TypeDescription
Array.<gadgets.Tab>Array of all existing tab objects

6.8.2.7 removeTab

removeTab(tabIndex)

Description: Removes a tab at tabIndex and all of its associated content.

Parameters:

NameTypeDescription
tabIndexNumberIndex of the tab to remove

6.8.2.8 setSelectedTab

setSelectedTab(tabIndex)

Description: Selects the tab at tabIndex and fires the tab's callback function if it exists. If the tab is already selected, the callback is not fired.

Parameters:

NameTypeDescription
tabIndexNumberIndex of the tab to select

6.8.2.9 swapTabs

swapTabs(tabIndex1, tabIndex2)

Description: Swaps the positions of tabs at tabIndex1 and tabIndex2. The selected tab does not change, and no callback functions are called.

Parameters:

NameTypeDescription
tabIndex1NumberIndex of the first tab to swap
tabIndex2NumberIndex of the secnod tab to swap

6.9 gadgets.window

Provides operations for getting information about and modifying the window the gadget is placed in.

6.9.1 Constructor

gadgets.window

6.9.2 Method Details

6.9.2.1 adjustHeight

<static> gadgets.window.adjustHeight(opt_height)

Description: Adjusts the gadget height.

Parameters:

NameTypeDescription
opt_heightNumberAn optional preferred height in pixels; If not specified, will attempt to fit the gadget to its content

6.9.2.2 getViewportDimensions

<static> Type: {Object} gadgets.window.getViewportDimensions()

Description: Detects the inner dimensions of a frame. See http://www.quirksmode.org/dom/w3c_cssom for more information.

Returns:

TypeDescription
ObjectAn object with width and height properties

6.9.2.3 setTitle

<static> gadgets.window.setTitle(title)

Description: Sets the gadget title.

Parameters:

NameTypeDescription
titleStringThe preferred title

6.10 JavaScript Internationalization (i18n)

A container MUST emit the OpenSocial JavaScript internationalization libraries and data files required by the libraries if an application requires the feature <Require feature="opensocial-i18n"/>. The container SHOULD emit the OpenSocial JavaScript internationalization libraries and data files required by the libraries if an application optionallly requests the feature <Optional feature="opensocial-i18n"/>.

6.10.1 gadgets.i18n

Class for internationalization features.

6.10.2 Formatting/Parsing using Predefined Patterns is Done within Default Locale

Gadgets locale is set at render time. The i18n package above will use getCountry and getLanguage to load the corresponding formatter/parser for that locale if any of the functions in the package are invoked. For example, let's say gadgets has lanuguage as french and country as france, the i18n package will use formatter/parser following french conventions by default. That means gadget developers could format/parse French date/time/number/currency using the predefined CURRENCY_PATTERN.

Example

           
gadgets.i18n.parseNumber(gadgets.i18n.CURRENCY_PATTERN, "20 000 \u20AC"); // will return 20000

They could also parse foreign currency by passing in a opt_currencyCode. Note when French writes an amount of foreign currency, they will still use the French way of writing numbers the positioning currency code - just the currency code is different.

Example

           
gadgets.i18n.parseNumber(gadgets.i18n.CURRENCY_PATTERN, "20 000 $", 0, "USD"); // will return 20000

It gets a little bit complicated if a foreign currency written in the foreign way is to be parsed. In that case, predefined patterns won't work, and string patterns need to be used. The example below returns 0 (indicating error in parsing), as the number presented is not in French format.

Example

           
gadgets.i18n.parseNumber(gadgets.i18n.CURRENCY_PATTERN, "$20,000"); // will return 0, indicating error

To make this work, a string pattern needs to be passed in, like what is done below:

Example

           
gadgets.i18n.parseNumber("#,###", "$20,000", 0, "USD"); // will return 20000

6.10.3 Pattern Specification

6.10.3.1 Date/Time Pattern Specification

Both Formatting and Parsing following the same pattern specification. The date/time pattern specifications are found in Unicode Locale Data Markup Language, Date Format Patterns The following specifiers are not required in this release:

6.10.3.2 Number Pattern Specification

Many characters in a pattern are taken literally; they are matched during parsing and output unchanged during formatting. Special characters, on the other hand, stand for other characters, strings, or classes of characters. For example, the '#' character is replaced by a localized digit. Often the replacement character is the same as the pattern character; in the U.S. locale, the ',' grouping character is replaced by ','. However, the replacement is still happening, and if the symbols are modified, the grouping character changes. Some special characters affect the behavior of the formatter by their presence; for example, if the percent character is seen, then the value is multiplied by 100 before being displayed.

To insert a special character in a pattern as a literal, that is, without any special meaning, the character must be quoted. There are some exceptions to this which are noted below.

The characters listed here are used in non-localized patterns. Localized patterns use the corresponding characters taken from corresponding locale symbol collection. Two exceptions are the currency sign and quote, which are not localized.

SymbolLocationLocalized?Meaning
0NumberYesDigit
#NumberYesDigit, zero shows as absent.
.NumberYesDecimal separator or monetary decimal separator.
-NumberYesMinus sign
,NumberYesGrouping Separator
ENumberYesSeparates mantizza and exponent in scientific notation. Need not be quoted in prefix or suffix.
;Subpattern boundaryYesSeparates positive and negative subpatterns.
%Prefix or suffixYesMultiply by 100 and show as percentage.
\u2030Prefix or suffixYesMultiply by 1000 and show as per mile.
¤ (\u00A4)Prefix or suffixNoCurrency sign, replaced by currency symbol. If doubled, replaced by international currency symbol. If present in a pattern, the monetary decimal separator is used instead of the decimal separator.
'Prefix or suffixNoUsed to quote special characters in a prefix or suffix, for example, "'#'#" formats 123 to "#123". To create a single quote itself, use two in a row: "# o''clock".

A NumberFormat pattern contains a postive and negative subpattern, for example, "#,##0.00;(#,##0.00)". Each subpattern has a prefix, a numeric part, and a suffix. If there is no explicit negative subpattern, the negative subpattern is the localized minus sign prefixed to the positive subpattern. That is, "0.00" alone is equivalent to "0.00;-0.00". If there is an explicit negative subpattern, it serves only to specify the negative prefix and suffix; the number of digits, minimal digits, and other characteristics are ignored in the negative subpattern. That means that "#,##0.0#;(#)" has precisely the same result as "#,##0.0#;(#,##0.0#)".

The prefixes, suffixes, and various symbols used for infinity, digits, thousands separators, decimal separators, etc. may be set to arbitrary values, and they will appear properly during formatting. However, care must be taken that the symbols and strings do not conflict, or parsing will be unreliable. For example, the decimal separator and thousands separator should be distinct characters, or parsing will be impossible.

The grouping separator is a character that separates clusters of integer digits to make large numbers more legible. It commonly used for thousands, but in some locales it separates ten-thousands. The grouping size is the number of digits between the grouping separators, such as 3 for "100,000,000" or 4 for "1 0000 0000".

6.10.3.2.1 Pattern BNF

 pattern := subpattern (';' subpattern)?
subpattern := prefix? number exponent? suffix?
 number :=
(integer ('.' fraction)?) | sigDigits
 prefix :=
'\u0000'..'\uFFFD' - specialCharacters
 suffix :=
'\u0000'..'\uFFFD' - specialCharacters
 integer := '#'* '0'*
'0'
 fraction := '0'* '#'*
 sigDigits := '#'* '@'
'@'* '#'*
 exponent := 'E' '+'? '0'* '0'
 padSpec
:= '*' padChar
 padChar := '\u0000'..'\uFFFD' -
quote
 
 Notation:
 X* 0 or more
instances of X
 X? 0 or 1 instances of X
 X|Y
either X or Y
 C..D any character from C up to D,
inclusive
 S-T characters in S, except those in T

The first subpattern is for positive numbers. The second (optional) subpattern is for negative numbers.

6.10.4 Field Details

6.10.4.1 CURRENCY_PATTERN

<static> Member of: gadgets.i18n.CURRENCY_PATTERN

Description: Pattern for currency.

6.10.4.2 DECIMAL_PATTERN

<static> Member of: gadgets.i18n.DECIMAL_PATTERN

Description: Pattern for decimal numbers.

6.10.4.3 FULL_DATE_FORMAT

<static> Member of: gadgets.i18n.FULL_DATE_FORMAT

Description: Format for full representations of dates.

6.10.4.4 FULL_DATETIME_FORMAT

<static> Member of: gadgets.i18n.FULL_DATETIME_FORMAT

Description: Format for short representations of datetimes.

6.10.4.5 FULL_TIME_FORMAT

<static> Member of: gadgets.i18n.FULL_TIME_FORMAT

Description: Format for full representations of times.

6.10.4.6 LONG_DATE_FORMAT

<static> Member of: gadgets.i18n.LONG_DATE_FORMAT

Description: Format for long representations of dates.

6.10.4.7 LONG_DATETIME_FORMAT

<static> Member of: gadgets.i18n.LONG_DATETIME_FORMAT

Description: Format for short representations of datetimes.

6.10.4.8 LONG_TIME_FORMAT

<static> Member of: gadgets.i18n.LONG_TIME_FORMAT

Description: Format for long representations of times.

6.10.4.9 MEDIUM_DATE_FORMAT

<static> Member of: gadgets.i18n.MEDIUM_DATE_FORMAT

Description: Format for medium representations of dates.

6.10.4.10 MEDIUM_DATETIME_FORMAT

<static> Member of: gadgets.i18n.MEDIUM_DATETIME_FORMAT

Description: Format for medium representations of datetimes.

6.10.4.11 MEDIUM_TIME_FORMAT

<static> Member of: gadgets.i18n.MEDIUM_TIME_FORMAT

Description: Format for medium representations of times.

6.10.4.12 PERCENT_PATTERN

<static> Member of: gadgets.i18n.PERCENT_PATTERN

Description: Pattern for percentages.

6.10.4.13 SCIENTIFIC_PATTERN

<static> Member of: gadgets.i18n.SCIENTIFIC_PATTERN

Description: Pattern for scientific numbers.

6.10.4.14 SHORT_DATE_FORMAT

<static> Member of: gadgets.i18n.SHORT_DATE_FORMAT

Description: Format for short representations of dates.

6.10.4.15 SHORT_DATETIME_FORMAT

<static> Member of: gadgets.i18n.SHORT_DATETIME_FORMAT

Description: Format for short representations of datetimes.

6.10.4.16 SHORT_TIME_FORMAT

<static> Member of: gadgets.i18n.SHORT_TIME_FORMAT

Description: Format for short representations of times.

6.10.5 Method Details

6.10.5.1 formatDateTime

<static> Type: {string} gadgets.i18n.formatDateTime(pattern, date)

Description: This method formats a "Date" object with provided pattern specification. The pattern could be a string using ICU notation or a predefined pattern. A string using ICU notation offers the most flexibility. Each field as specified in the pattern has locale specific behavior. The pattern string is allowed to contain string literals, and one type of pattern might not work for all locales. In those case, the pattern itself could also be locale specific, thus not good for sharing among locales.

Example

date = new Date(2006, 6, 27, 13, 10, 10, 250);
assertEquals("13:10:10", gadgets.i18n.formatDateTime("HH:mm:ss", date));

Parameters:

NameTypeDescription
patternstring/numberString to specify patterns or Number used to reference predefined pattern that a date should be formatted into.
dateDateDate object being formatted.

Returns:

TypeDescription
stringstring representation of date/time.

6.10.5.2 formatNumber

<static> Type: {string} gadgets.i18n.formatNumber(pattern, value, opt_currencyCode)

Description: Format number using the pattern specified. The pattern could be a string pattern or one of the predefined patterns. The formatted string is returned. If an error is encountered, zero will be returned.

Example

var str = gadgets.i18n.formatNumber("#,###", 1234567890);
assertEquals("1,234,567,890", str);
var str = gadgets.i18n.formatNumber(gadgets.i18n.CURRRENCY_PATTERN, 1234.569);
assertEquals("$1,234.58", str);

Parameters:

NameTypeDescription
patternstring/numberString to specify patterns or Number used to reference predefined pattern that a number should be formatted into.
valuenumberThe number being formatted.
opt_currencyCodestringoptional international currency code, it determines the currency code/symbol should be used in format/parse. If not given, the currency code for current locale will be used.

Returns:

TypeDescription
stringThe formatted string.

6.10.5.3 parseDateTime

<static> Type: {number} gadgets.i18n.parseDateTime(pattern, text, start, date)

Description: This method will parse the input string ("text"), interpretting it as specified by pattern. The parsed result will be saved into a Date object ("date"). "start" indicates from where in the string the parse should start. This method returns the number of characters consumed.

Example

assertTrue(gadgets.i18n.parseDateTime("yyMMdd", "991202", 0, date) > 0);
assertEquals(1999, date.getFullYear());
assertTrue(date.getMonth() == 12 - 1);
assertTrue(date.getDate() == 02);
assertTrue(gadgets.i18n.parseDateTime("yyyyMMdd", "20051202", 0, date) > 0);
assertEquals(2005, date.getFullYear());
assertTrue(date.getMonth() == 12 - 1);
assertTrue(date.getDate() == 02);   

A whole piece of string is usually the target for parsing. But in some cases, you might just want to parse part of the string, "start" parameter and return value also make it very convenient. For example, suppose you want to parse a string like "88/01, 99/03, 98/05, 97/02", the following code will do the job.

Example

var date_array = []
var pos = 0;
var text = "88/01, 99/03, 98/05, 97/02";
while(1) {
 var date = new Date;
    var consumed = gadgets.i18n.parseDateTime("yy/MM", text, pos, date);
    if (consumed <= 0) break;
    date_array.push(date);
    pos += consumed;
    if (pos < text.length && text[pos] == ',') ++pos;
    if (pos < text.length && text[pos] == ' ') ++pos;
}

Similar to the formatting functions, a predefined pattern could also be passed in as the first parameter.

Example

//assume locale has already been set to zh_CN
var date = new Date();
gadgets.i18n.parseDateTime(gadgets.i18n.LONG_DATE_FORMAT, "2006?7?24?", 0, date);
assertEquals(date.getFullYear(), 2006);
assertEquals(date.getMonth(), 7 - 1);
assertEquals(date.getDate(), 24);

Parameters:

NameTypeDescription
patternstring/numberString to specify patterns or Number used to reference predefined pattern that a date should be parsed from.
textstringThe string that need to be parsed.
startnumberThe character position in "text" where parse begins.
dateDateThe date object that will hold parsed value.

Returns:

TypeDescription
numberThe number of characters advanced or 0 if failed.

6.10.5.4 parseNumber

<static> Type: {number} gadgets.i18n.parseNumber(pattern, text, opt_pos, opt_currencyCode)

Description: Parse string to get a number the pattern specified. The pattern could be a string pattern or one of the predefined patterns.

Example

var value = gadgets.i18n.parseNumber("0E0", "1.2345E+4");
assertEquals(12345.0, value);
//assume locale has already been set to fr
var value = gadgets.i18n.parseNumber(gadgets.i18n.CURRENCY_PATTERN, "0,30 ?");
assertEquals(0.30, value);

Parameters:

NameTypeDescription
patternstring/numberString to specify patterns or Number used to reference predefined pattern that a number should be parsed from.
textstringinput text being parsed.
opt_posArrayoptional one element array that holds position information. It tells from where parse should begin. Upon return, it holds parse stop position.
opt_currencyCodestringoptional international currency code, it determines the currency code/symbol should be used in format/parse. If not given, the currency code for current locale will be used.

Returns:

TypeDescription
numberParsed number, 0 if in error.

7. References

[RFC2119]Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels" , RFC 2119, March 1997.
[RFC2606]Eastlake, D. and A. Panitz, "Reserved Top Level DNS Names" , RFC 2606, June 1999.
[RFC2616]Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, "Hypertext Transfer Protocol -- HTTP/1.1" , RFC 2616, June 1999.
[Caja] "Caja Project" , January 2009, <http://code.google.com/p/google-caja/>.
[JSON-RPC]social, o., "OpenSocial JSON RPC Protocol Specification 0.9" , November 2007, <RPC-Protocol.html>.
[xsdpart1]Thompson, H.S., Beech, D., Maloney, M., and N. Mendelsohn, "XML Schema Part 1: Structures Second Edition" , October 2004, <http://www.w3.org/TR/xmlschema-1/>.

Author's Address

OpenSocial and Gadgets Specification Group <opensocial-and-gadgets-spec@googlegroups.com>EMail:

A. Gadgets Extended XSD

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Module">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="ModulePrefs" minOccurs="0">
          <xs:complexType>
            <xs:choice minOccurs="0" maxOccurs="unbounded">
              <xs:element name="Require" type="GadgetFeatureType"/>
              <xs:element name="Optional" type="GadgetFeatureType"/>
              <xs:element name="Preload">
                <xs:complexType>
                  <xs:attribute name="href" type="xs:string" use="required"/>
                  <xs:attribute name="authz" default="none">
                    <xs:simpleType>
                      <xs:restriction base="xs:string">
                        <xs:enumeration value="none"/>
                        <xs:enumeration value="signed"/>
                        <xs:enumeration value="oauth"/>
                      </xs:restriction>
                    </xs:simpleType>
                  </xs:attribute>
                  <xs:attribute name="sign_owner" type="xs:boolean" default="true"/>
                  <xs:attribute name="sign_viewer" type="xs:boolean" default="true"/>
                  <xs:attribute name="views" type="xs:string" use="optional"/>
                  <xs:attribute name="oauth_service_name" type="xs:string" use="optional"/>
                  <xs:attribute name="oauth_token_name" type="xs:string" use="optional"/>
                  <xs:attribute name="oauth_request_token" type="xs:string" use="optional"/>
                  <xs:attribute name="oauth_request_token_secret" type="xs:string" use="optional"/>
                </xs:complexType>
              </xs:element>
              <xs:element name="Icon">
                <xs:complexType>
                  <xs:simpleContent>
                    <xs:extension base="xs:string">
                      <xs:attribute name="mode">
                        <xs:simpleType>
                          <xs:restriction base="xs:string">
                            <xs:enumeration value="base64"/>
                          </xs:restriction>
                        </xs:simpleType>
                      </xs:attribute>
                      <xs:attribute name="type" type="xs:string"/>
                    </xs:extension>
                  </xs:simpleContent>
                </xs:complexType>
              </xs:element>
              <xs:element name="Locale">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="msg" minOccurs="0" maxOccurs="unbounded">
                      <xs:complexType>
                        <xs:simpleContent>
                          <xs:extension base="xs:string">
                            <xs:attribute name="name" type="xs:string" use="required"/>
                            <xs:attribute name="desc" type="xs:string" use="optional"/>
                          </xs:extension>
                        </xs:simpleContent>
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                  <xs:attribute name="lang" type="xs:string" use="optional"/>
                  <xs:attribute name="country" type="xs:string" use="optional"/>
                  <xs:attribute name="messages" type="xs:string" use="optional"/>
                  <xs:attribute name="language_direction">
                    <xs:simpleType>
                      <xs:restriction base="xs:string">
                        <xs:enumeration value="ltr"/>
                        <xs:enumeration value="rtl"/>
                      </xs:restriction>
                    </xs:simpleType>
                  </xs:attribute>
                </xs:complexType>
              </xs:element>
              <xs:element name="Link">
                <xs:complexType>
                  <xs:attribute name="href" type="xs:string" use="required"/>
                  <xs:attribute name="rel" type="xs:string" use="required">
                    <xs:simpleType>
                      <xs:restriction base="xs:string">
                        <xs:enumeration value="gadgets.help"/>
                        <xs:enumeration value="gadgets.support"/>
                        <xs:enumeration value="icon"/>
                      </xs:restriction>
                    </xs:simpleType>
                  </xs:attribute>
                </xs:complexType>
              </xs:element>
              <xs:element name="OAuth" minOccurs="0" maxOccurs="1">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="Service" maxOccurs="unbounded">
                      <xs:complexType>
                        <xs:sequence>
                          <xs:element name="Request" type="OAuthResourceType" minOccurs="0"/>
                          <xs:element name="Access" type="OAuthResourceType" minOccurs="0"/>
                          <xs:element name="Authorization" minOccurs="0">
                            <xs:complexType>
                              <xs:attribute name="url" type="xs:string" use="required"/>
                            </xs:complexType>
                          </xs:element>
                        </xs:sequence>
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                  <xs:attribute name="name" type="xs:string" use="optional"/>
                </xs:complexType>
              </xs:element>
            </xs:choice>
            <xs:attribute name="title" type="xs:string" use="optional"/>
            <xs:attribute name="title_url" type="xs:string" use="optional"/>
            <xs:attribute name="description" type="xs:string" use="optional"/>
            <xs:attribute name="author" type="xs:string" use="optional"/>
            <xs:attribute name="author_email" type="xs:string" use="optional"/>
            <xs:attribute name="screenshot" type="xs:string" use="optional"/>
            <xs:attribute name="thumbnail" type="xs:string" use="optional"/>
            <xs:attribute name="directory_title" type="xs:string" use="optional"/>
            <xs:attribute name="author_affiliation" type="xs:string" use="optional"/>
            <xs:attribute name="author_location" type="xs:string" use="optional"/>
            <xs:attribute name="author_photo" type="xs:string" use="optional"/>
            <xs:attribute name="author_aboutme" type="xs:string" use="optional"/>
            <xs:attribute name="author_quote" type="xs:string" use="optional"/>
            <xs:attribute name="author_link" type="xs:string" use="optional"/>
            <xs:attribute name="show_stats" type="xs:boolean" use="optional"/>
            <xs:attribute name="show_in_directory" type="xs:boolean" use="optional"/>
            <xs:attribute name="string" type="xs:string" use="optional"/>
            <xs:attribute name="width" type="xs:int" use="optional"/>
            <xs:attribute name="height" type="xs:int" use="optional"/>
            <xs:attribute name="category" type="xs:string" use="optional"/>
            <xs:attribute name="category2" type="xs:string" use="optional"/>
            <xs:attribute name="singleton" type="xs:boolean" use="optional"/>
            <xs:attribute name="render_inline" type="xs:string" use="optional"/>
            <xs:attribute name="scaling" type="xs:boolean" use="optional"/>
            <xs:attribute name="scrolling" type="xs:boolean" use="optional"/>
          </xs:complexType>
        </xs:element>
        <xs:element name="UserPref" minOccurs="0" maxOccurs="unbounded">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="EnumValue" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                  <xs:attribute name="value" type="xs:string" use="required"/>
                  <xs:attribute name="display_value" type="xs:string" use="optional"/>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
            <xs:attribute name="name" type="xs:string" use="required"/>
            <xs:attribute name="display_name" type="xs:string" use="optional"/>
            <xs:attribute name="default_value" type="xs:string" use="optional"/>
            <xs:attribute name="required" type="xs:string" use="optional"/>
            <xs:attribute name="datatype" default="string">
              <xs:simpleType>
                <xs:restriction base="xs:string">
                  <xs:enumeration value="string"/>
                  <xs:enumeration value="hidden"/>
                  <xs:enumeration value="bool"/>
                  <xs:enumeration value="enum"/>
                  <xs:enumeration value="list"/>
                  <xs:enumeration value="number"/>
                  <xs:enumeration value="location"/>
                </xs:restriction>
              </xs:simpleType>
            </xs:attribute>
            <xs:attribute name="urlparam" type="xs:string" use="optional"/>
            <xs:attribute name="autocomplete_url" type="xs:string" use="optional"/>
            <xs:attribute name="num_minval" type="xs:double" use="optional"/>
            <xs:attribute name="num_maxval" type="xs:double" use="optional"/>
            <xs:attribute name="str_maxlen" type="xs:int" use="optional"/>
            <xs:attribute name="restrict_to_completions" type="xs:boolean" use="optional"/>
            <xs:attribute name="prefix_match" type="xs:boolean" use="optional"/>
            <xs:attribute name="publish" type="xs:boolean" use="optional"/>
            <xs:attribute name="listen" type="xs:boolean" use="optional"/>
            <xs:attribute name="on_change" type="xs:string" use="optional"/>
            <xs:attribute name="group" type="xs:string" use="optional"/>
          </xs:complexType>
        </xs:element>
        <xs:element name="Content" minOccurs="1" maxOccurs="unbounded">
          <xs:complexType>
            <xs:simpleContent>
              <xs:extension base="xs:string">
                <xs:attribute name="type" use="optional" default="html">
                  <xs:simpleType>
                    <xs:restriction base="xs:string">
                      <xs:enumeration value="html"/>
                      <xs:enumeration value="url"/>
                      <xs:enumeration value="html-inline"/>
                    </xs:restriction>
                  </xs:simpleType>
                </xs:attribute>
                <xs:attribute name="href" type="xs:string" use="optional"/>
                <xs:attribute name="view" type="xs:string" use="optional"/>
                <xs:attribute name="preferred_height" type="xs:integer" use="optional"/>
                <xs:attribute name="preferred_width" type="xs:integer" use="optional"/>
              </xs:extension>
            </xs:simpleContent>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:complexType name="GadgetFeatureType">
    <xs:sequence>
      <xs:element name="Param" minOccurs="0" maxOccurs="unbounded">
        <xs:complexType>
          <xs:simpleContent>
            <xs:extension base="xs:string">
              <xs:attribute name="name" type="xs:string" use="required"/>
            </xs:extension>
          </xs:simpleContent>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
    <xs:attribute name="feature" type="xs:string" use="required"/>
  </xs:complexType>
  <xs:complexType name="OAuthResourceType">
    <xs:attribute name="url" type="xs:string" use="required"/>
    <xs:attribute name="method" use="optional" default="GET">
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:enumeration value="GET"/>
          <xs:enumeration value="POST"/>
        </xs:restriction>
      </xs:simpleType>
    </xs:attribute>
    <xs:attribute name="param_location" use="optional" default="header">
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:enumeration value="header"/>
          <xs:enumeration value="url"/>
          <xs:enumeration value="body"/>
        </xs:restriction>
      </xs:simpleType>
    </xs:attribute>
  </xs:complexType>
</xs:schema>

B. Canonical Gadget XSD

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Module">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="ModulePrefs" minOccurs="0">
          <xs:complexType>
            <xs:choice minOccurs="0" maxOccurs="unbounded">
              <xs:element name="Require" type="GadgetFeatureType"/>
              <xs:element name="Optional" type="GadgetFeatureType"/>
              <xs:element name="Preload">
                <xs:complexType>
                  <xs:attribute name="href" type="xs:string" use="required"/>
                  <xs:attribute name="authz" default="none">
                    <xs:simpleType>
                      <xs:restriction base="xs:string">
                        <xs:enumeration value="none"/>
                        <xs:enumeration value="signed"/>
                        <xs:enumeration value="oauth"/>
                      </xs:restriction>
                    </xs:simpleType>
                  </xs:attribute>
                  <xs:attribute name="sign_owner" type="xs:boolean" default="true"/>
                  <xs:attribute name="sign_viewer" type="xs:boolean" default="true"/>
                  <xs:attribute name="views" type="xs:string" use="optional"/>
                  <xs:attribute name="oauth_service_name" type="xs:string" use="optional"/>
                  <xs:attribute name="oauth_token_name" type="xs:string" use="optional"/>
                  <xs:attribute name="oauth_request_token" type="xs:string" use="optional"/>
                  <xs:attribute name="oauth_request_token_secret" type="xs:string" use="optional"/>
                </xs:complexType>
              </xs:element>
              <xs:element name="Icon">
                <xs:complexType>
                  <xs:simpleContent>
                    <xs:extension base="xs:string">
                      <xs:attribute name="mode">
                        <xs:simpleType>
                          <xs:restriction base="xs:string">
                            <xs:enumeration value="base64"/>
                          </xs:restriction>
                        </xs:simpleType>
                      </xs:attribute>
                      <xs:attribute name="type" type="xs:string"/>
                    </xs:extension>
                  </xs:simpleContent>
                </xs:complexType>
              </xs:element>
              <xs:element name="Locale">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="msg" minOccurs="0" maxOccurs="unbounded">
                      <xs:complexType>
                        <xs:simpleContent>
                          <xs:extension base="xs:string">
                            <xs:attribute name="name" type="xs:string" use="required"/>
                            <xs:attribute name="desc" type="xs:string" use="optional"/>
                          </xs:extension>
                        </xs:simpleContent>
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                  <xs:attribute name="lang" type="xs:string" use="optional"/>
                  <xs:attribute name="country" type="xs:string" use="optional"/>
                  <xs:attribute name="messages" type="xs:string" use="optional"/>
                  <xs:attribute name="language_direction">
                    <xs:simpleType>
                      <xs:restriction base="xs:string">
                        <xs:enumeration value="ltr"/>
                        <xs:enumeration value="rtl"/>
                      </xs:restriction>
                    </xs:simpleType>
                  </xs:attribute>
                </xs:complexType>
              </xs:element>
              <xs:element name="Link">
                <xs:complexType>
                  <xs:attribute name="href" type="xs:string" use="required"/>
                  <xs:attribute name="rel" type="xs:string" use="required">
                    <xs:simpleType>
                      <xs:restriction base="xs:string">
                        <xs:enumeration value="gadgets.help"/>
                        <xs:enumeration value="gadgets.support"/>
                        <xs:enumeration value="icon"/>
                      </xs:restriction>
                    </xs:simpleType>
                  </xs:attribute>
                </xs:complexType>
              </xs:element>
              <xs:element name="OAuth" minOccurs="0" maxOccurs="1">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="Service" maxOccurs="unbounded">
                      <xs:complexType>
                        <xs:sequence>
                          <xs:element name="Request" type="OAuthResourceType" minOccurs="0"/>
                          <xs:element name="Access" type="OAuthResourceType" minOccurs="0"/>
                          <xs:element name="Authorization" minOccurs="0">
                            <xs:complexType>
                              <xs:attribute name="url" type="xs:string" use="required"/>
                            </xs:complexType>
                          </xs:element>
                        </xs:sequence>
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                  <xs:element name="Rating">
                    <xs:complexType>
                      <xs:attribute name="scheme" type="xs:anyURI" use="optional" default=""/>
                    </xs:complexType>
                  </xs:element>
                  <xs:attribute name="name" type="xs:string" use="optional"/>
                </xs:complexType>
              </xs:element>
            </xs:choice>
            <xs:attribute name="title" type="xs:string" use="optional"/>
            <xs:attribute name="title_url" type="xs:string" use="optional"/>
            <xs:attribute name="description" type="xs:string" use="optional"/>
            <xs:attribute name="author" type="xs:string" use="optional"/>
            <xs:attribute name="author_email" type="xs:string" use="optional"/>
            <xs:attribute name="screenshot" type="xs:string" use="optional"/>
            <xs:attribute name="thumbnail" type="xs:string" use="optional"/>
          </xs:complexType>
        </xs:element>
        <xs:element name="UserPref" minOccurs="0" maxOccurs="unbounded">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="EnumValue" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                  <xs:attribute name="value" type="xs:string" use="required"/>
                  <xs:attribute name="display_value" type="xs:string" use="optional"/>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
            <xs:attribute name="name" type="xs:string" use="required"/>
            <xs:attribute name="display_name" type="xs:string" use="optional"/>
            <xs:attribute name="default_value" type="xs:string" use="optional"/>
            <xs:attribute name="required" type="xs:string" use="optional"/>
            <xs:attribute name="datatype" default="string">
              <xs:simpleType>
                <xs:restriction base="xs:string">
                  <xs:enumeration value="string"/>
                  <xs:enumeration value="hidden"/>
                  <xs:enumeration value="bool"/>
                  <xs:enumeration value="enum"/>
                  <xs:enumeration value="list"/>
                  <xs:enumeration value="number"/>
                </xs:restriction>
              </xs:simpleType>
            </xs:attribute>
          </xs:complexType>
        </xs:element>
        <xs:element name="Content" minOccurs="1" maxOccurs="unbounded">
          <xs:complexType>
            <xs:simpleContent>
              <xs:extension base="xs:string">
                <xs:attribute name="type" use="optional" default="html">
                  <xs:simpleType>
                    <xs:restriction base="xs:string">
                      <xs:enumeration value="html"/>
                      <xs:enumeration value="url"/>
                    </xs:restriction>
                  </xs:simpleType>
                </xs:attribute>
                <xs:attribute name="href" type="xs:string" use="optional"/>
                <xs:attribute name="view" type="xs:string" use="optional"/>
                <xs:attribute name="preferred_height" type="xs:integer" use="optional"/>
                <xs:attribute name="preferred_width" type="xs:integer" use="optional"/>
              </xs:extension>
            </xs:simpleContent>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:complexType name="GadgetFeatureType">
    <xs:sequence>
      <xs:element name="Param" minOccurs="0" maxOccurs="unbounded">
        <xs:complexType>
          <xs:simpleContent>
            <xs:extension base="xs:string">
              <xs:attribute name="name" type="xs:string" use="required"/>
            </xs:extension>
          </xs:simpleContent>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
    <xs:attribute name="feature" type="xs:string" use="required"/>
  </xs:complexType>
  <xs:complexType name="OAuthResourceType">
    <xs:attribute name="url" type="xs:string" use="required"/>
    <xs:attribute name="method" use="optional" default="GET">
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:enumeration value="GET"/>
          <xs:enumeration value="POST"/>
        </xs:restriction>
      </xs:simpleType>
    </xs:attribute>
    <xs:attribute name="param_location" use="optional" default="auth-header">
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:enumeration value="auth-header"/>
          <xs:enumeration value="uri-query"/>
          <xs:enumeration value="post-body"/>
        </xs:restriction>
      </xs:simpleType>
    </xs:attribute>
  </xs:complexType>
</xs:schema>

C. Message Bundle Schema

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="messagebundle">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="msg" minOccurs="0" maxOccurs="unbounded">
          <xs:complexType>
            <xs:simpleContent>
              <xs:extension base="xs:string">
                <xs:attribute name="name" type="xs:string" use="required"/>
                <xs:attribute name="desc" type="xs:string" use="optional"/>
              </xs:extension>
            </xs:simpleContent>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

D. Application Version Schema

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="app">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="gadget" minOccurs="1">
          <xs:complexType>
            <xs:choice>
              <xs:element name="label" minOccurs="0" maxOccurs="unbounded">
                <xs:simpleType>
                  <xs:union>
                    <xs:simpleType>
                      <xs:restriction base="xs:string"/>
                    </xs:simpleType>
                    <xs:simpleType>
                      <xs:restriction base="xs:string">
                        <xs:enumeration value="current"/>
                        <xs:enumeration value="development"/>
                      </xs:restriction>
                    </xs:simpleType>
                  </xs:union>
                </xs:simpleType>
              </xs:element>
              <xs:element name="spec" type="xs:anyURI" minOccurs="1"/>
            </xs:choice>
            <xs:attribute name="version" type="xs:string" use="required"/>
            <xs:attribute name="container" type="xs:string" use="optional"/>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>