| 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
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].
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:
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.
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.
The core gadget API, this translates gadget XML into content that can be rendered in a browser, typically in an IFRAME.
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.
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.
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.
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.
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.
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.
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:
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:
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>
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.
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.
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.
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.
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.
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.
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:
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.
Namespace for top-level people functions.
gadgets
<static> gadgets.log(message)
Description: Log an informational message.
Parameters:
| Name | Type | Description |
|---|---|---|
| message | Object | The message to log |
<static> gadgets.warn(message)
Description: Log a warning message.
Parameters:
| Name | Type | Description |
|---|---|---|
| message | Object | The message to log |
<static> gadgets.error(message)
Description: Log an error message.
Parameters:
| Name | Type | Description |
|---|---|---|
| message | Object | The message to log |
<static> gadgets.setLogLevel(logLevel)
Description: Sets the log level threshold.
Parameters:
| Name | Type | Description |
|---|---|---|
| logLevel | Number | New log level threshold. |
Used by gadgets.setLogLevel (Section 5.1.2.4).
<static> Member of: gadgets.log
Description: Log level for informational logging.
<static> Member of: gadgets.log
Description: Log level for warning logging.
<static> Member of: gadgets.log
Description: Log level for error logging.
<static> Member of: gadgets.log
Description: Log level for no logging.
Provides remote content retrieval functions.
gadgets.io
<static> Type: {String} gadgets.io.encodeValues(fields)
Description: Converts an input object into a URL-encoded data string. (key=value&...)
Parameters:
| Name | Type | Description |
|---|---|---|
| fields | Object | The post fields you wish to encode |
Returns:
| Type | Description |
|---|---|
| String | The processed post data; this includes a trailing ampersand (&) |
<static> Type: {String} gadgets.io.getProxyUrl(url, opt_params)
Description: Gets the proxy version of the passed-in URL.
Parameters:
| Name | Type | Description |
|---|---|---|
| url | String | The URL to get the proxy URL for |
| opt_params | Map<String|String> | Additional optional parameters (Section 5.6) to pass to the request |
Returns:
| Type | Description |
|---|---|
| String | The proxied version of the URL |
<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);
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.
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.
The following additional parameters may be specified in opt_params:
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.
The makeRequest() callback parameter is passed a javascript object with several OAuth-specific fields in addition to the normal values returned by makeRequest():
| Name | Type | Description |
|---|---|---|
| url | String | The URL where the content is located |
| callback | Function | The 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_params | Map.<gadgets.io.RequestParameters|Object> | Additional request parameters (Section 5.7) or proxy request parameters (Section 5.6) |
Used by RequestParameters (Section 5.7).
gadgets.io.AuthorizationType
<static> Member of: gadgets.io.AuthorizationType.NONE
Description: No authorization. This field may be used interchangeably with the string 'NONE'.
<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'.
<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'.
Used by RequestParameters (Section 5.7).
gadgets.io.ContentType
<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'.
<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'.
<static> Member of: gadgets.io.ContentType.JSON
Description: Returns a JSON object. This field may be used interchangeably with the string 'JSON'.
<static> Member of: gadgets.io.ContentType.TEXT
Description: Returns text; used for fetching HTML. This field may be used interchangeably with the string 'TEXT'.
Defines values for RequestParameters.METHOD (Section 5.7.2.5).
gadgets.io.MethodType
<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'.
<static> Member of: gadgets.io.MethodType.GET
Description: The default type. This field may be used interchangeably with the string 'GET'.
<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'.
<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'.
<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'.
Used by gadgets.io.getProxyUrl() (Section 5.2.2.2) method.
gadgets.io.ProxyUrlRequestParameters
<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'.
Used by the gadgets.io.makeRequest() (Section 5.2.2.3) method.
gadgets.io.RequestParameters
<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'.
<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'.
<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'.
<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'.
<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'.
<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'.
<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'.
<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'.
Provides operations for translating objects to and from JSON.
gadgets.json
<static> Type: {Object} gadgets.json.parse(text)
Description: Parses a JSON string, producing a JavaScript value.
Parameters:
| Name | Type | Description |
|---|---|---|
| text | String | The string to transform into an object; usually the result of a previous stringify call |
Returns:
| Type | Description |
|---|---|
| Object | The object parsed from the passed in text; false if an error occurred |
<static> Type: {String} gadgets.json.stringify(v)
Description: Converts a JavaScript value to a JSON string.
Parameters:
| Name | Type | Description |
|---|---|---|
| v | Object | The object to convert |
Returns:
| Type | Description |
|---|---|
| String | The JSON equivalent |
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();
gadgets.Prefs(opt_moduleId)
Creates a new Prefs object.
Parameters:
| Name | Type | Description |
|---|---|---|
| opt_moduleId | String | Number | An optional parameter specifying the module ID to create prefs for; if not provided, the default module ID is used |
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:
| Name | Type | Description |
|---|---|---|
| key | String | The preference to fetch |
Returns:
| Type | Description |
|---|---|
| Array.<String> | The preference; if not set, an empty array |
Type: {Boolean} getBool(key)
Description: Retrieves a preference as a boolean.
Parameters:
| Name | Type | Description |
|---|---|---|
| key | String | The preference to fetch |
Returns:
| Type | Description |
|---|---|
| Boolean | The preference; if not set, false |
Type: {String} getCountry()
Description: Gets the current country, returned as ISO 3166-1 alpha-2 code.
Returns:
| Type | Description |
|---|---|
| String | The country for this module instance |
Type: {Number} getFloat(key)
Description: Retrieves a preference as a floating-point value.
Parameters:
| Name | Type | Description |
|---|---|---|
| key | String | The preference to fetch |
Returns:
| Type | Description |
|---|---|
| Number | The preference; if not set, 0 |
Type: {Number} getInt(key)
Description: Retrieves a preference as an integer.
Parameters:
| Name | Type | Description |
|---|---|---|
| key | String | The preference to fetch |
Returns:
| Type | Description |
|---|---|
| Number | The preference; if not set, 0 |
Type: {String} getLang()
Description: Gets the current language the gadget should use when rendering, returned as a ISO 639-1 language code.
Returns:
| Type | Description |
|---|---|
| String | The language for this module instance |
Type: {String | Number} getModuleId()
Description: Gets the module ID for the current instance.
Returns:
| Type | Description |
|---|---|
| String | Number | The module ID for this module instance |
Type: {String} getMsg(key)
Description: Fetches an unformatted message.
Parameters:
| Name | Type | Description |
|---|---|---|
| key | String | The message to fetch |
Returns:
| Type | Description |
|---|---|
| String | The message |
Type: {String} getString(key)
Description: Retrieves a preference as a string.
Parameters:
| Name | Type | Description |
|---|---|---|
| key | String | The preference to fetch |
Returns:
| Type | Description |
|---|---|
| String | The preference; if not set, an empty string |
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:
| Name | Type | Description |
|---|---|---|
| key | String | The pref to store |
| val | Object | The values to store |
setArray(key, val)
Description: Stores an array preference. To use this call, the gadget must require the feature setprefs.
Parameters:
| Name | Type | Description |
|---|---|---|
| key | String | The pref to store |
| val | Array | The values to store |
Provides general-purpose utility functions.
gadgets.util
<static> Type: {String} gadgets.util.escapeString(str)
Description: Escapes the input using HTML entities to make it safer. The following characters are affected:
Parameters:
| Name | Type | Description |
|---|---|---|
| str | String | The string to escape |
Returns:
| Type | Description |
|---|---|
| String | The escaped string |
<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:
| Name | Type | Description |
|---|---|---|
| feature | String | The feature to get parameters for |
Returns:
| Type | Description |
|---|---|
| Object | The parameters for the given feature, or null |
<static> Type: {Boolean} gadgets.util.hasFeature(feature)
Description: Returns whether the specified feature is supported.
Parameters:
| Name | Type | Description |
|---|---|---|
| feature | String | The feature to test for |
Returns:
| Type | Description |
|---|---|
| Boolean | True if the feature is supported |
<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:
| Name | Type | Description |
|---|---|---|
| callback | Function | The handler to run. The callback function will not be called until after the existing callstack has completed execution. |
<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:
| Name | Type | Description |
|---|---|---|
| text | String | arbitrary text string |
Returns:
| Type | Description |
|---|---|
| String | a sanitized version that may include HTML tags, but will not execute script. |
<static> Type: {String} gadgets.util.unescapeString(str)
Description: Reverses escapeString
Parameters:
| Name | Type | Description |
|---|---|---|
| str | String | The string to unescape. |
Returns:
| Type | Description |
|---|---|
| String | The unescaped string |
Provides operations for dealing with views.
See also: gadgets.views.View (Section 5.12)
gadgets.views
<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:
| Name | Type | Description |
|---|---|---|
| urlTemplate | A url template for a container view | |
| environment | A set of named variables (for example, [[]OWNER | PATH | PARAMS | NAME]) of type string. |
Returns:
| Type | Description |
|---|---|
| String | A URL string |
<static> Type: { gadgets.views.View (Section 5.12) } gadgets.views.getCurrentView()
Description: Returns the current view.
Returns:
| Type | Description |
|---|---|
| gadgets.views.View (Section 5.12) | The current view |
<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:
| Type | Description |
|---|---|
| Map.<String|String> | The parameter map |
<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:
| Type | Description |
|---|---|
| Map<gadgets.views.ViewType | String|gadgets.views.View> | All supported views, keyed by their name attribute. |
<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:
| Name | Type | Description |
|---|---|---|
| | | 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_ownerId | String | The ID of the owner of the page to navigate to; defaults to the current owner |
Base interface for all view objects.
gadgets.views.View()
NOTE: CONSTRUCTOR SHOULD NOT BE DOCUMENTED
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:
| Name | Type | Description |
|---|---|---|
| environment | A set of named variables (for example, [[]OWNER | PATH | PARAMS | NAME]) of type string. |
Returns:
| Type | Description |
|---|---|
| String | A URL string |
Type: { gadgets.views.ViewType (Section 5.13) | String} getName()
Description: Returns the name of this view.
Returns:
| Type | Description |
|---|---|
| gadgets.views.ViewType (Section 5.13) | String | The view name, usually specified as a gadgets.views.ViewType |
Type: {String} getUrlTemplate()
Description: Returns a string URI template conforming to the IETF spec draft with variables for substitution.
Four variables are supported:
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:
| Type | Description |
|---|---|
| String | A template that can be used to construct URLs that navigate to this view |
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:
| Type | Description |
|---|---|
| boolean | True if the gadget is the only visible gadget; otherwise, false |
Used by View (Section 5.12) s.
gadgets.views.ViewType
<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'.
<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'.
<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'.
<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'.
Embeds Flash content in gadgets.
gadgets.flash
<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:
| Type | Description |
|---|---|
| Boolean | Whether the function call completes successfully |
<static> Type: {Boolean} gadgets.flash.embedFlash(swfUrl, swfContainer, swfVersion, opt_params)
Description: Injects a Flash file into the DOM tree.
Parameters:
| Name | Type | Description |
|---|---|---|
| swfUrl | String | SWF URL |
| swfContainer | String | Object | The ID or object reference of an existing HTML container element |
| swfVersion | Number | Minimum Flash Player version required |
| opt_params | Object | An optional object that may contain any valid HTML parameter; all attributes will be passed through to the Flash movie on creation |
Returns:
| Type | Description |
|---|---|
| Boolean | Whether the function call completes successfully |
<static> Type: {Number} gadgets.flash.getMajorVersion()
Description: Detects Flash Player and its major version.
Returns:
| Type | Description |
|---|---|
| Number | The major version of Flash Player or 0 if Flash is not supported |
MiniMessage class, used to create messages that will appear to the user within the gadget. Typical use cases:
gadgets.MiniMessage(opt_moduleId, opt_container)
Creates a MiniMessage.
Parameters:
| Name | Type | Description |
|---|---|---|
| opt_moduleId | String | Optional module ID |
| opt_container | HTMLElement | Optional HTML container element where mini-messages will appear |
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:
| Name | Type | Description |
|---|---|---|
| message | String | Object | The message as an HTML string or DOM element |
| opt_callback | Function | Optional 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:
| Type | Description |
|---|---|
| HTMLElement | HTML element of the created message |
Type: {HTMLElement} createStaticMessage(message)
Description: Creates a static message that can only be dismissed programmatically (by calling dismissMessage()).
Parameters:
| Name | Type | Description |
|---|---|---|
| message | String | Object | The message as an HTML string or DOM element |
Returns:
| Type | Description |
|---|---|
| HTMLElement | HTML element of the created message |
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:
| Name | Type | Description |
|---|---|---|
| message | String | Object | The message as an HTML string or DOM element |
| seconds | number | Number of seconds to wait before dismissing the message |
| opt_callback | Function | Optional 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:
| Type | Description |
|---|---|
| HTMLElement | HTML element of the created message |
dismissMessage(message)
Description: Dismisses the specified message.
Parameters:
| Name | Type | Description |
|---|---|---|
| message | HTMLElement | HTML element of the message to remove |
OAuth popup window manager.
Expected usage:
// 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();
gadgets.oauth.Popup(destination, windowOptions, openCallback, closeCallback)
Description: used to create a new OAuth popup window manager.
Parameters:
| Name | Type | Description |
|---|---|---|
| destination | String | Target URL for the popup window. |
| windowOptions | String | Options for window.open, used to specify look and feel of the window. |
| openCallback | Function | Function to call when the window is opened. |
| closeCallback | Function | Function to call when the window is closed. |
Type: {Function} createOpenerOnClick()
Returns:
| Type | Description |
|---|---|
| Function | an onclick handler for the "open the approval window" link. |
Type: {Function} createApprovedOnClick()
Returns:
| Type | Description |
|---|---|
| Function | an 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. |
Provides operations for making remote procedure calls for gadget-to-container, container-to-gadget, and gadget-to-gadget communication.
gadgets.rpc
<static> gadgets.rpc.call(targetId, serviceName, callback, var_args)
Description: Calls an RPC service.
Parameters:
| Name | Type | Description |
|---|---|---|
| targetId | String | ID of the RPC service provider; empty if calling the parent container |
| serviceName | String | Service name to call |
| callback | Function|null | Callback 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 |
<static> gadgets.rpc.register(serviceName, handler)
Description: Registers an RPC service.
Parameters:
| Name | Type | Description |
|---|---|---|
| serviceName | String | Service name to register |
| handler | Function | Service handler |
<static> gadgets.rpc.registerDefault(handler)
Description: Registers a default service handler to process all unknown remote procedure calls, which fail silently by default.
Parameters:
| Name | Type | Description |
|---|---|---|
| handler | Function | Service handler |
<static> gadgets.rpc.unregister(serviceName)
Description: Unregisters an RPC service.
Parameters:
| Name | Type | Description |
|---|---|---|
| serviceName | String | Service name to unregister |
<static> gadgets.rpc.unregisterDefault()
Description: Unregisters the default service handler. Future unknown remote procedure calls will fail silently.
Provides operations for getting display information about the currently shown skin.
gadgets.skins
<static> Type: {String} gadgets.skins.getProperty(propertyKey)
Description: Fetches the display property mapped to the given key.
Parameters:
| Name | Type | Description |
|---|---|---|
| propertyKey | String | The key to get data for; keys are defined in gadgets.skins.Property (Section 6.6) |
Returns:
| Type | Description |
|---|---|
| String | The data |
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.
gadgets.skins.Property
<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'.
<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'.
<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'.
<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'.
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)
gadgets.Tab()
NOTE: CONSTRUCTOR SHOULD NOT BE DOCUMENTED
Type: {Function} getCallback()
Description: Returns the callback function that is executed when the tab is selected.
Returns:
| Type | Description |
|---|---|
| Function | The callback function of the tab |
Type: {HTMLElement} getContentContainer()
Description: Returns the HTML element where the tab content is rendered.
Returns:
| Type | Description |
|---|---|
| HTMLElement | The HTML element of the content container |
Type: {Number} getIndex()
Description: Returns the tab's index.
Returns:
| Type | Description |
|---|---|
| Number | The tab's index |
Type: {String} getName()
Description: Returns the label of the tab as a string (may contain HTML).
Returns:
| Type | Description |
|---|---|
| String | The label of the tab |
Type: {HTMLElement} getNameContainer()
Description: Returns the HTML element that contains the tab's label.
Returns:
| Type | Description |
|---|---|
| HTMLElement | The HTML element of the tab's label |
A class gadgets can use to make tabs.
gadgets.TabSet(opt_moduleId, opt_defaultTab, opt_container)
Creates a new TabSet object
Parameters:
| Name | Type | Description |
|---|---|---|
| opt_moduleId | String | Optional suffix for the ID of tab container |
| opt_defaultTab | String | Optional 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_container | HTMLElement | The HTML element to contain the tabs; if omitted, a new div element is created and inserted at the very top |
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:
Parameters:
| Name | Type | Description |
|---|---|---|
| tabName | String | Label of the tab to create |
| opt_params | Object | Optional parameter object |
Returns:
| Type | Description |
|---|---|
| String | DOM id of the tab container |
alignTabs(align, opt_offset)
Description: Sets the alignment of tabs. Tabs are center-aligned by default.
Parameters:
| Name | Type | Description |
|---|---|---|
| align | String | 'left', 'center', or 'right' |
| opt_offset | Number | Optional parameter to set the number of pixels to offset tabs from the left or right edge; the default value is 3px |
displayTabs(display)
Description: Shows or hides tabs and all associated content.
Parameters:
| Name | Type | Description |
|---|---|---|
| display | Boolean | True to show tabs; false to hide tabs |
Type: {HTMLElement} getHeaderContainer()
Description: Returns the tab headers container element.
Returns:
| Type | Description |
|---|---|
| HTMLElement | The tab headers container element |
Type: { gadgets.Tab (Section 6.7) } getSelectedTab()
Description: Returns the currently selected tab object.
Returns:
| Type | Description |
|---|---|
| gadgets.Tab (Section 6.7) | The currently selected tab object |
Type: {Array.<gadgets.Tab>} getTabs()
Description: Returns an array of all existing tab objects.
Returns:
| Type | Description |
|---|---|
| Array.<gadgets.Tab> | Array of all existing tab objects |
removeTab(tabIndex)
Description: Removes a tab at tabIndex and all of its associated content.
Parameters:
| Name | Type | Description |
|---|---|---|
| tabIndex | Number | Index of the tab to remove |
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:
| Name | Type | Description |
|---|---|---|
| tabIndex | Number | Index of the tab to select |
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:
| Name | Type | Description |
|---|---|---|
| tabIndex1 | Number | Index of the first tab to swap |
| tabIndex2 | Number | Index of the secnod tab to swap |
Provides operations for getting information about and modifying the window the gadget is placed in.
gadgets.window
<static> gadgets.window.adjustHeight(opt_height)
Description: Adjusts the gadget height.
Parameters:
| Name | Type | Description |
|---|---|---|
| opt_height | Number | An optional preferred height in pixels; If not specified, will attempt to fit the gadget to its content |
<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:
| Type | Description |
|---|---|
| Object | An object with width and height properties |
<static> gadgets.window.setTitle(title)
Description: Sets the gadget title.
Parameters:
| Name | Type | Description |
|---|---|---|
| title | String | The preferred title |
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"/>.
Class for internationalization features.
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
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:
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.
| Symbol | Location | Localized? | Meaning |
|---|---|---|---|
| 0 | Number | Yes | Digit |
| # | Number | Yes | Digit, zero shows as absent. |
| . | Number | Yes | Decimal separator or monetary decimal separator. |
| - | Number | Yes | Minus sign |
| , | Number | Yes | Grouping Separator |
| E | Number | Yes | Separates mantizza and exponent in scientific notation. Need not be quoted in prefix or suffix. |
| ; | Subpattern boundary | Yes | Separates positive and negative subpatterns. |
| % | Prefix or suffix | Yes | Multiply by 100 and show as percentage. |
| \u2030 | Prefix or suffix | Yes | Multiply by 1000 and show as per mile. |
| ¤ (\u00A4) | Prefix or suffix | No | Currency 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 suffix | No | Used 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".
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.
<static> Member of: gadgets.i18n.CURRENCY_PATTERN
Description: Pattern for currency.
<static> Member of: gadgets.i18n.DECIMAL_PATTERN
Description: Pattern for decimal numbers.
<static> Member of: gadgets.i18n.FULL_DATE_FORMAT
Description: Format for full representations of dates.
<static> Member of: gadgets.i18n.FULL_DATETIME_FORMAT
Description: Format for short representations of datetimes.
<static> Member of: gadgets.i18n.FULL_TIME_FORMAT
Description: Format for full representations of times.
<static> Member of: gadgets.i18n.LONG_DATE_FORMAT
Description: Format for long representations of dates.
<static> Member of: gadgets.i18n.LONG_DATETIME_FORMAT
Description: Format for short representations of datetimes.
<static> Member of: gadgets.i18n.LONG_TIME_FORMAT
Description: Format for long representations of times.
<static> Member of: gadgets.i18n.MEDIUM_DATE_FORMAT
Description: Format for medium representations of dates.
<static> Member of: gadgets.i18n.MEDIUM_DATETIME_FORMAT
Description: Format for medium representations of datetimes.
<static> Member of: gadgets.i18n.MEDIUM_TIME_FORMAT
Description: Format for medium representations of times.
<static> Member of: gadgets.i18n.PERCENT_PATTERN
Description: Pattern for percentages.
<static> Member of: gadgets.i18n.SCIENTIFIC_PATTERN
Description: Pattern for scientific numbers.
<static> Member of: gadgets.i18n.SHORT_DATE_FORMAT
Description: Format for short representations of dates.
<static> Member of: gadgets.i18n.SHORT_DATETIME_FORMAT
Description: Format for short representations of datetimes.
<static> Member of: gadgets.i18n.SHORT_TIME_FORMAT
Description: Format for short representations of times.
<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:
| Name | Type | Description |
|---|---|---|
| pattern | string/number | String to specify patterns or Number used to reference predefined pattern that a date should be formatted into. |
| date | Date | Date object being formatted. |
Returns:
| Type | Description |
|---|---|
| string | string representation of date/time. |
<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:
| Name | Type | Description |
|---|---|---|
| pattern | string/number | String to specify patterns or Number used to reference predefined pattern that a number should be formatted into. |
| value | number | The number being formatted. |
| opt_currencyCode | string | optional 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:
| Type | Description |
|---|---|
| string | The formatted string. |
<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:
| Name | Type | Description |
|---|---|---|
| pattern | string/number | String to specify patterns or Number used to reference predefined pattern that a date should be parsed from. |
| text | string | The string that need to be parsed. |
| start | number | The character position in "text" where parse begins. |
| date | Date | The date object that will hold parsed value. |
Returns:
| Type | Description |
|---|---|
| number | The number of characters advanced or 0 if failed. |
<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:
| Name | Type | Description |
|---|---|---|
| pattern | string/number | String to specify patterns or Number used to reference predefined pattern that a number should be parsed from. |
| text | string | input text being parsed. |
| opt_pos | Array | optional one element array that holds position information. It tells from where parse should begin. Upon return, it holds parse stop position. |
| opt_currencyCode | string | optional 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:
| Type | Description |
|---|---|
| number | Parsed number, 0 if in error. |
| [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/>. |
<?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>
<?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>
<?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>
<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>