Demoxi Widgets Developer's Guide

version 0.8.1.570
Copyright 2007-2008, Demoxi, Inc.

Table of Contents

Back to top

Getting Started

Demoxi widgets are powerful and handy little tools for interacting with identity-related resources. They are surprisingly easy to create. In fact, if you know HTML, CSS, and JavaScript, you are well on your way.

Basically, widgets are small web applications that are displayed through the Demoxi desktop rather than in a browser. Widgets are not meant to be full-blown applications that are used continuously for hours. Instead, widgets are small utilities that present small, targeted, and often dynamic, chunks of information.

In its simplest form, a widget consists of nothing more than an HTML file and an XML definition file. Of course, most widgets include other files, such as image files (PNG and JPG), style sheets (CSS), and scripting (Javascript and VBScript source files). All of the content is stored in a ZIP file that is renamed with a DW extension. You can grab a widget online, rename it with a ZIP extension, and easily explore its contents. It's a good way to peek into other widgets and see how they are made.

To get started with Demoxi widgets:

  1. Download the the Demoxi Widget SDK from http://demoxi.com/labs/api/widget/widget-sdk.zip.
  2. Extract the ZIP file to /Program Files/demoxi/identity/[version]/widgets.
  3. To make the Hello, World, run ..\bin\perl makedw.pl -w hello -d hello.dw.
  4. From your Internet browser, open http://localhost:4073/Widget/Open/Hello.
  5. That's it!

The rest of this document describes the Hello, World example widget in detail, decomposes a widget into components, and describes how to package your widget. Also, check out the Demoxi Widget API Reference, which offers a growing set of services to widget developers.

Back to top

Your First Widget

To get a sense of how a widget works, let's look at the classic Hello, World example.

(The Hello, World widget floating over a blue Windows desktop)

This example is no different from standard Ajax/HTML that you would use for a regular web page that accesses web services. Here are the files which you can find in the SDK hello directory:

We'll build up the classic Hello, World example from scratch showing each step along the way:

The HTML Body

Here's the widget index.html page:

   <body style="background-image: url
('image/widget.png');background-repeat:
no-repeat;">
<div class="drag"></div>
<div id="title">Hello, World!</div>
<div id="airplane">
<img src="image/plane.jpeg" height="55%">
<br><br>
Time to get this thing off the ground!
</div>
<div id="dataDiv">
<textarea id="data1" rows="1" cols="29">
</textarea><br>
<textarea id="data2" rows="7" cols="29">
</textarea><br>
<textarea id="data3" rows="2" cols="29">
</textarea>
</div>
<div id="footer">
<a href="http://localhost:4073/Widget/Close/
<TMPL_VAR handle>">
<img src="image/close.gif" alt="close">
</a>
</div>
</body>

This is pretty typical HTML with styles defined by the hello.css style sheet. However there are a few things to note:

Skinning Your Widget

A widget skin requires two files, a widget background and a transparency mask. The transparency mask is a monochrome bitmap that defines transparent areas. Transparent areas are shown black, non-transparent areas are shown white. For our Hello, World example, image/widget.png defines the widget background and image/mask.bmp defines the transparency mask:

image/widget.png

image/mask.bmp

Some Fancy Tricks

jQuery (http://docs.jquery.com) is an open-source JavaScript library that is shipped with Demoxi that let's you do some fancy stuff with your widgets.

For example, to access your widget page as soon as possible, use the jQuery function $(document).ready. As you can see from index.html, we do a couple of interesting things there:

   $(document).ready(function()
{
// Version
getVersion ();

// Set-up dragging
$("body")
.dblclick (function () {
$.get ('http://localhost:4073/Widget/
BeginDrag/' + <TMPL_VAR handle>);
})
$(".drag")
.mousedown (function () {
$.get ('http://localhost:4073/Widget/
BeginDrag/' + <TMPL_VAR handle>);
})
.css ({cursor: "url('/image/
cursor_hand_open.cur')"});

// Add a drop shadow to the airplane images
$("#airplane img").shadow ({color: "black"});

// Access some vault attributes
and widget properties
setVaultAttributes();
setWidgetProperties();
});

In this function, we get the Demoxi platform version, set-up dragging, enlist jQuery to add a drop shadow to our airplane image, set some user vault attributes, and some widget-specific attributes.

Using the Widget Services

To use the widget services, it's best to use the jQuery ajax function since it allows for error handling. For example, to get the Demoxi platform version:

   $.ajax({
url: "http://localhost:4073/Widget/GetVersion/
<TMPL_VAR handle>"
,type: "GET"
,data: "personal.language=English&personal.
yob=1992&address.co=United States&
personal.gender=M&address.postcode=
98001"
,dataType: "json"
,error: function (xhr) {
$("#data1").html (
"The Demoxi Widget API is
supported after version 0.8.1.568.
Please update your Demoxi version."
);
}
,success: function (result) {
$("#data1").html (
"Demoxi version: " +
result.major + "." +
result.minor + "." +
result.revision + "." +
result.build
);
}
});

In Hello, World, first we call SetProperties to set the widget properties property1 and property2. We then call GetProperties to retrieve those same properties and load them into the data div. Note that the returned data is easily accessed using JSON.

We follow the same process to set and get user attributes using SetVaultAttributes and GetVaultAttributes:

   $.ajax({
url: "http://localhost:4073/Widget/SetVaultAttributes/<TMPL_VAR handle>"
,type: "GET"
,data: "personal.language=English&personal.yob=1992&address.co=United
States&personal.gender=M&address.postcode=98001",dataType: "json"
,error: function (xhr) {$("#data2").html (xhr.responseText + "
[HTTP status: " + xhr.status + "]"
);
}
,success: function () {
$.ajax({
url: "http://localhost:4073/Widget/GetVaultAttributes/<TMPL_VAR
handle>"
,type: "GET"
,data: "personal.language&personal.yob&address.co&personal.
gender&address.postcode"
,dataType: "json"
,error: function (xhr) {
$("#data2").html (
xhr.responseText + "
[HTTP status: " + xhr.status + "]"
);
}
,success: function (result){
$("#data2").html (
"Your Demoxi ID is
<TMPL_VAR userName><br>" +
"You were born in " + result.
personal.yob + "<br>" +
"You are " + (result.personal.
gender == "M" ? "male" : "female")
+ "<br>" +
"You live in " + result.address.co
+ "<br>" +
"Your postal code is " +
result.address.postcode + "<br>" +
"Your language is " + result.
personal.language
);
}
});
}
});

See Demoxi Widget API Reference for a list of all widget services.

Dragging Your Widget

To drag your widget, you need to establish a draggable area and then call the BeginDrag service. From $(document).ready shown about, we allow dragging when the user presses the mouse button over the drag div or when the user double-clicks anywhere on the widget:

   $("body")
.dblclick (function () {
$.get ('http://localhost:4073/Widget/BeginDrag/' + <TMPL_VAR handle>);
})
$(".drag")
.mousedown (function () {
$.get ('http://localhost:4073/Widget/BeginDrag/' + <TMPL_VAR handle>);
})
.css ({cursor: "url('/image/
cursor_hand_open.cur')"});

Packaging Your Widget

Widgets are packaged in a ZIP format file, which is renamed to have a DW extension. A widget DW file must contain a minimum of three files:

  1. The manifest.xml defines the widget and tells the Demoxi platform where to look for other widget files;
  2. A transparency mask in windows bitmap BMP format; and
  3. The signatures.xml ensures that the file contents are as designed and not tampered with. signatures.xml is automatically generated by the makedw.pl Perl script utility.

To make your DW widget bundle, use the makedw.pl Perl script:

   ..\bin\perl makedw.pl -widgetdir hello -dwfile 
hello.dw

where hello is the widget directory and hello.dw is the resulting DW file. makedw.pl puts hello.dw in the Demoxi widgets directory. Once that's done, you can bring your widget to life like this http://localhost:4073/Widget/Open/Hello

Back to top

Components of a Widget

HTML

Since the implementation of a widget is nothing more than a small Web application, you have access to the DOM and most of the APIs as you would with a standard Web page. This means you can use Ajax techniques, create dynamic HTML elements, trap events, and so on. You can also use APIs from the Demoxi Widget API Reference. These APIs provide a way for your widget to interface with the Demoxi platform when implementing identity-centric functionality.

Cascading Style Sheets (CSS)

As with any web page, style sheets are an essential part of designing good-looking widgets. Thus a good understanding of Cascading Style Sheets (CSS) is critical when producing a professional-looking widget.

The style sheet can be defined directly in the main html page or in a separate style sheet file. Just remember that if you do use a separate stylesheet file, it must be listed inside the signature.xml file.

JavaScript

In keeping with the use of web technologies, Demoxi widgets use JavaScript to provide dynamic behavior and rich functionality. JavaScript in Demoxi works the same way as it does in any browser, and, as in any HTML page, you can attach JavaScript actions to any user interface element.

In order for a web page in HTML to act like a widget, it must follow certain conventions. These include provision for moving the widget around with the mouse, among other things.

We have found jQuery (http://www.jquery.com) to be very helpful in implementing these extensions. jQuery is a fast, concise, JavaScript Library that simplifies how you traverse HTML documents, handle events, perform animations, and add Ajax interactions to your web pages, and we highly recommend it. There are also several handy jQuery plugins located in the /html/script/jquery directory.

Dragging

Demoxi widgets can be dragged by attaching an event to a DOM element and calling BeginDrag. For example, to allow all drag classes to be draggable, you'd execute the following when the page loads:

   $(".drag")
.mousedown (function () {
$.get ('http://localhost:4073/Widget/BeginDrag/' + <TMPL_VAR handle>);
})
.css ({cursor: "url('/image/cursor_hand_open.
cur')"});

Skins

As is typical of most widget frameworks, Demoxi widgets do not support arbitrary resizing. However, there are times when it might make sense to offer different sizes of the same widget functionality; a messaging widget might want to offer small, medium, and large variations of the widget window. Skins are the mechanism through with widget developers can support this capability.

The skin is specified in the background-image style within the body tag in the HTML file. The transparency mask is specified in the manifest's SKIN tag.

Icons

Each widget can specify how it is presented in the Demoxi desktop dock in one of two ways. First, it can specify a static icon. An icon is a transparent PNG file with a default size of 64x64. The default size of the icon is not rigidly enforced. Instead, the Demoxi desktop dock proportionately scales the icon to fit its space inside the dock using the system's HTML scaling functions. If the widget writer wishes to use an icon of a different size, it is highly recommended that the icons be larger, as they tend to scale more attractively.

For a more dynamic appearance, the developer can define an active icon. An active icon is in effect a very tiny version of the widget, which in turn becomes of its own icon. When docked, this icon is as active as any larger, open widget. The active icon can be nothing more than a scaled version of the full widget, or it can show a different, abbreviated view of the same information.

The active icon is defined in the manifest as an additional skin that is used solely when the widget is docked. In all other ways, the active icon is identical to a full widget.

Strings

Demoxi widgets are designed to be easily localized to other languages. A key mechanism for doing so is the strings.xml file. Instead of hard-coding text strings into the widget's HTML, all strings are defined within the strings.xml file.

Every Demoxi user must select a preferred language when they are creating their wallet. When rendering a widget, the Demoxi server will match this language code against those listed inside the widget's manifest. If that language is available, the server will reference this set of strings when rendering the widget's HTML.

When a developer wishes to add support for a language all they have to do is amend the strings.xml file. In the following example, the widget supports English, Spanish, and Norwegian:

   <STRINGS>
      <LANG id="eng">
         <STR id="hello">Hello, World!</STR>
         <STR id="head">Where is the head?</STR>
         <STR id="beer">I'd like another beer.</STR>
      </LANG>
      <LANG id="spa">
         <STR id="hello">Hola, muno!</STR>
         <STR id="head">Donde es el bano?</STR>
         <STR id="beer">Una cerveza mas!</STR>
      </LANG>
      <LANG id="nno">
         <STR id="hello">Hei, alles!</STR>
         <STR id="head">Hvor es VCen?</STR>
         <STR id="beer">Mas beer, vaer sao snill!
</STR> </LANG> </STRINGS>

In addition, the widget manifest would contain the following:

   <STRINGS default="eng">
      <LANG>eng \strings\strings.xml</LANG>
      <LANG>spa \strings\strings.xml</LANG>
      <LANG>nno \strings\strings.xml</LANG>
   </STRINGS>

Demoxi uses the three letter codes (e.g. eng for English) as defined in Tags for the Identification of Languages (RFC 3066-2bis , http://www.ietf.org/rfc/rfc3066.txt). Demoxi supports UTF-8 encoding, thus supporting both single- and double-byte character sets.

In the example above, the developer included all the strings for the supported languages in a single strings.xml file. For reasons of modularity, a developer may want to break up the strings.xml file into discrete files, one for each language. If so, we recommend a naming convention of strings_xx.xml, where xx is the two-letter code for that language, e.g. strings_en.xml. The manifest entries would then reference the individual files accordingly.

Demoxi does not currently support more granular language definitions such as en-us (English as spoken in the United States) as opposed to en-ca (English as spoken in Canada). In this case, the word aboot should be hard-coded.

Help

The Demoxi platform also makes it easy for widget developers to offer online, contextual help.

   <HELP default="eng">
      <ITEM> \help\help1.eng.html </ITEM>
   </HELP>

Whenever Demoxi tries to load an asset (a button inside a widget, for example), it looks to see if there is a help entry attached to it. If so, it then looks for that file, say help1.html. However, it also considers the language setting of the user. Say the user is Spanish (language code of spa). While rendering the widget, Demoxi will first look for help1.spa.html. If it cannot find it, it will then look for help1.html. The benefit of this system is that the widget writer only has to refer to the help file name in one way in the content html file. However, if the author decides to offer help in other languages, the widget will automatically present the appropriate help in the language needed without any additional coding on the part if the developer.

Back to top

Packaging a Widget

Packaging a widget requires a set of files, a Manifest file, and a Signatures file bundled into a DW file. The Perl utility makedw.pl is used to make this file.

Directories and Files

All widgets are stored as DW files in the Demoxi/identity/widgets directory. Each widget DW file will have an internal directory structure:

   \bundle
      \strings
      \help
      \image

Manifest

A Demoxi widget is defined by the manifest.xml file, and is the glue that holds a Demoxi widget together. Most of elements in the manifest are used for displaying the widget either on the desktop or within the Demoxi desktop dock. Functional elements are listed within the manifest as a list of Perl script files such as those for background processes. It should be noted that the manifest does not contain links to all of the files in the widget; it only contains links to the major main HTML file and major directories, each of which may have links to other files.

A typical manifest is shown below for a Demoxi widget. As you can see, a basic widget contains the following files:

As a widget grows, you can place other files, such as images and external CSS and JavaScript files, into the widget's bundle.

   <MANIFEST version="1.0">
      <WIDGET>
         <NAME>Hello, World!</NAME>
         <VERSION>1.0</VERSION>
         <DESCRIPTION>
            This is a simple "Hello, World" type 
application. Its job is to show some basic ideas of how to build a widget. </DESCRIPTION> <ICON>icon.png</ICON> <SKIN default="1" name="small"> <ROOT>index.html</ROOT> <MASK>image/mask.bmp</MASK> <TITLE>Hello, World</TITLE> </SKIN> </WIDGET> <STRINGS default="en"> <LANG id="en"> <STR id="hello">Hello, World!</STR> <STR id="head">Where is the head?</STR> <STR id="beer">I'd like another beer.</STR> </LANG> </STRINGS> <PUBLISHER> <NAME>Demoxi, Inc.</NAME> <LOGO>image/icon.png</LOGO> <COPYRIGHT>Copyright Demoxi, Inc. 2007
</COPYRIGHT> <URL>http://www.demoxi.com/</URL>; </PUBLISHER> </MANIFEST>

Signatures

To prevent hackers from inserting malicious code into a widget, each widget file of the must be secured through the signatures.xml. It is automatically generated by the makedw.pl Perl script.

When the widget is loaded, the signatures are checked them against the values listed in this file. This prevents hackers from inserting malicious code into a widget.

Signatures is a bit of a misnomer for this file, as it contains only a single digital signature. It does, however, contain SHA1 hashes for each widget component. The signature is then applied over the filenames and the hashes, sorted alphabetically (increasing dictionary sort, ASCII order), with ASCII tab (0x09) byte characters appended to each string. The overall digital signature is generated using the RSA signature scheme.

Here's an example Signatures file:

   <SIGNATURES>
      <FILE name="mask.bmp">
6dcfXufJLW3J6S/9rRe4vUlBj5g</FILE> <FILE name="image/plane.jpeg">
hKUWhBuneltGSN4s0N/LMOpG27Q</FILE> <FILE name="index.html">hvfkN/qlp/
zhXR3cuerq6jd2Z7g</FILE> <SIGNATURE>DigestMethod: sha1 EncodingMethod: base64 Signature: | BMo+
PEX02uXAPkYk64ecoDA+ZEFxRasdB+HiZAq6LcFHItKY8s/ 1c6Z7PtPhik6Evp96T99Q5oi0sY8dH8SyuQ== </SIGNATURE> </SIGNATURES>

It is important to contrast the signatures.xml file with the manifest.xml file. The manifest describes the major components of the widget, but does not require an exhaustive list of every file in every subdirectory within the widget. The signatures.xml file, on the other hand, must list every individual file used within the widget, including files in all subfolders, and associate a unique hash with each of those files. This is necessary to ensure the security of the entire widget.

Making a DW File

To make a DW file, run the Perl script makedw.pl:

   ..\bin\perl makedw.pl -h
      | [-widgetdir or -w]
      | [-dwfile or -d]
   
   Options:
     -help         |  This help info
     -widgetdir    |  Input widget directory
     -dwfile       |  DW filename

If dwfile contains no path, the dwfile is put in the Demoxi widgets directory. This script also automatically generates the signature.xml file.

Back to top