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 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 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.
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.
Inputs:
- Gadget XML, typically specified as a URL pointing to a file on
the web.
- User prefs.
- Locale of the end user.
- (optional) IgnoreCache processing option.
- (optional) Module ID, an integer identifier for the gadget in a
given container context. If not provided, this defaults top
0.
Outputs:
- HTML, CSS, and JavaScript.
Process:
- Fetch the gadget XML.
- This SHOULD consult a cache to minimize load on the gadget XML
hosting server. The specific properties of caching are left to the
implementation.
- 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.
- 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.
- HTTP-based request servers SHOULD support this via a URL
parameter named
nocache.
- 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.
- Parse the gadget XML.
- The XML MUST conform to the extended gadget
spec XSD
.
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
contains 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.
- 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.
- Identify the Locale object corresponding to the request, and fetch messages specified by it.
- 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:
- The container MAY choose to utilize the rendered gadget's page fragment
for its own purposes. Gadget developers SHOULD NOT modify this value.
- 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.
- 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.
- Load the message bundle specified in the matched <Locale> element, if any.
- If the message attribute is specified, use it: load the bundle from the network using the provided URL.
- Otherwise use the <messagebundle> element that is a child of <Locale>, if present
- 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.
- Process message bundle into
__MSG_foo__ hangman
variables.
- The bundle MUST conform to the message bundle
XSD.
- For each message named
foo with value
bar, hangman
expansion __MSG_foo__ = bar.
- For each provided User Pref with key
foo and value
bar,
hangman expansion __UP_foo__ = bar.
- Hangman expansion
__MODULE_ID__ = <provided module
ID>.
- HTTP-based request servers SHOULD use the URL parameter named
mid for this.
- 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".
- 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:
Module.ModulePrefs attributes,
Module.Content@href,
Module.Content,
UserPref@display_name,
UserPref@default_value, and
UserPref.EnumValue@display_value
- Process gadget features, specified as
<Require> or
<Optional> in the gadget XML.
- 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.
- The message SHOULD list all requested features that could not
be used because the container does not support them.
- The message MAY provide contact information for the gadget
server administrator, along with a mechanism to request adding
support for the feature.
- 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.
- 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.
- Output gadget content.
- 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
- For type HTML gadgets, the order is as follows:
- Standard HTML header, opening
<html> tag and
<body>
tag. <head> information is optional. Gadgets run in browser
quirks mode.
- Core gadgets JavaScript libraries,
as specified here.
- Feature library initialization code, if needed.
- Processed gadget content, the result of steps #4 and possibly #5.
- A single call to
gadgets.util.runOnLoadHandlers();
- Standard HTML closing tags.
- For type URL gadgets, the provided URL MUST have the following
parameters added to it:
up_<name>=<value> for each provided user
preference.
lang=<language> and
country=<country>, from the
provided request Locale.
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.
- The server SHOULD consolidate all libs into a single request to
minimize the number of HTTP requests made by the client
browser.
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.
Context (container-side JavaScript):
It 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.
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 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.
Inputs:
- Same as for the Gadget Rendering Request.
Outputs:
- URL to a Gadget Rendering Request for the requested
gadget.
- Reference(s) to container JavaScript needed to satisfy needed
gadget API requests.
Process:
- Load and parse gadget XML as described in Gadget Rendering
Request steps #1 and #2.
- Process gadget features, specified as
<Require> or
<Optional> in the gadget XML.
- Emit an error message if a required feature is not
supported.
- Otherwise, for each requested, supported feature with
container-side JavaScript, enqueue this JavaScript to return to the
client.
- Construct URL to the corresponding Gadget Rendering Request,
generated as follows:
- Initialize URL using a static prefix.
- Add parameter
url=<url>, where
<url> is URL of the
requested gadget spec.
- Add user prefs parameters as described in Gadget Rendering
Request 6.ii.a.
- Add locale parameters as described in Gadget Rendering Request
6.ii.b.
- Return the enqueued container-side JavaScript and Gadget
Rendering Request URL.
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.
Input:
- Fixed path, computed by a static base URL combined with a path
fragment as described in Gadget Rendering Request part 6.ii.c.
Output:
- JavaScript code corresponding to the API(s) required by the
type URL gadget.
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.
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 <srcipt src=xxx> tags into one concatenating proxy fetch
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>
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.
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 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 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.
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.
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.
Attributes on the Content element map to makeRequest as follows:
- authz: gadgets.io.AuthorizationType (values are canonicalized by converting to lower case. Default value is 'none')
- oauth_service_name: gadgets.io.RequestParameters.OAUTH_SERVICE_NAME
- oauth_token_name: gadgets.io.RequestParameters.OAUTH_TOKEN_NAME
- oauth_request_token: gadgets.io.RequestParameters.OAUTH_REQUEST_TOKEN
- oauth_request_token_secret: gadgets.io.RequestParameters.OAUTH_REQUEST_TOKEN_SECRET
- sign_owner: gadgets.io.RequestParameters.SIGN_OWNER (default 'true')
- sign_viewer: gadgets.io.RequestParameters.SIGN_VIEWER (default 'true')
- refresh_interval: gadgets.io.RequestParameters.REFRESH_INTERVAL
Note that these attributes also apply to Preload elements.
The container MUST also add the following parameters to the URI query string:
- lang: The language of the user viewing the page as specified in Section 3 i under Process in this document.
- country: The country of the user viewing the page as specified in Section 3 i under Process in this document.
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.
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.
Caching
Containers SHOULD cache the results of the HTTP request following the recommendations of section 13 of RFC 2616.
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:
- The URI of the proxied request
- The opensocial owner id, if sign_owner is set to true and requests are authenticated
- The opensocial viewer id, if sign_viewer is set to true and requests are authenticated
- The language and country passed in to the proxied URI.
Containers MAY cache unsuccessful HTTP responses ("negative
caching"), but SHOULD NOT cache unsuccessful responses for a period
longer than 5 minutes.
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:
- If the document is a complete HTML document, including opening
and closing html tags, the container MUST retain the semantic meaning
of document type definition declarations as well as the relative
position of elements in the document
- A container MAY choose to move elements from the head of a
document and into the body (or vice versa), but the end result MUST
behave the same as the original input
- Containers MAY modify the document in other ways for optimization and security purposes as long as semantics are preserved
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.
All core APIs MUST be provided by the server in such a way as to conform
to the Gadgets API Reference. Gadget developers should not have to request any of these features, as the container should provide them all automatically.
The vast majority of gadgets
include one or more features. The more features a gadget server
supports, the more gadgets it supports. Thus, each gadget server
strongly SHOULD support as many such features as possible,
especially the following features that have high usage rates. Each
supplies a JavaScript API to be made available to the gadget.
Features are listed with their name(s) and their associated
API:
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"/>. Documentation on the internationalization libraries is
here.
The copyrights in this specification are licensed under the Creative Commons Attribution 2.5 license |
Terms of Service