IDE Widget Metadata Strawman Proposal

From MemberWiki

Jump to: navigation, search

Contents

Introduction

The following work-in-progress proposal attempts to express all of the features found in various widget systems and proposals that have been examined, including:

  • Adobe's proposal to IDE WG (1)
  • Apple Dashboard (3)
  • Dojo's dijit system (1)
  • IBM Widgets Proposal to Gadgets Task Force (2)
  • jMaki (1)
  • W3C Widgets (3)

where (1) is where "widget" means low-level UI controls, (2) is where "widget" means a mashup component, and (3) is where "widget" means a mini application that is installed onto the desktop or mobile device.

Example

The following example is adapted from the jMaki widget.json file for the Dojo clock widget and re-expressed in the proposed XML markup language for widgets.

jMaki's widget.json for Dojo clock widget

{
    "name" : "Clock",
    "type" : "dojo",
    'version' : '1.0',
    'jmakiVersion' : '1.0',    
    "image" : "images/dojo-clock.jpg",
    "description" : "This widget is a clock.",
    "args": [
        {"clockType" : {
           "type":"STRING", 
            "description" : "The clock type.",
            "defaultValue" : 'black',
             'values': [
                {'name' : 'Plain', 'value' : 'plain', 'description' : 'Clock with blue background.'},
                {'name' : 'Black', 'value' : 'black', 'description' : 'Clock with black background.'},
                {'name' : 'Black Texture', 'value' : 'blackTexture', 'description' : 'Clock with black texture background.'},
                {'name' : 'Gray', 'value' : 'gray', 'description' : 'Clock with gray background.'},
                {'name' : 'Gray Plastic', 'value' : 'grayPlastic', 'description' : 'Clock with gray plastic background.'}
               ]
            }
         },
    	{"timeZoneOffset": {
    	     "type":"NUMBER",
    	     "description": "The time Offset.",
    	     "defaultValue": 0
    	    }
    	 },
        {"label":{
            "type":"STRING",
            "description":"The label at the top of the clock.",   
            "defaultValue": ""
            }
        },
        {"labelColor":{
            "type":"STRING",
              "description":"The color of the label.",
              "defaultValue": "#000"
             }
         },
        {"topLabelColor":{
            "description":"The color of the label at the top of the clock.",
            "type":"STRING",
            "defaultValue": "#efefef"
           }
        },
        {"handColor":{
            "type":"STRING",
            "description":"The color of the clock hand.",
            "defaultValue": "#788598"
             }
         },
        {"handBorderColor": {
            "type":"STRING",
            "description":"The color of the borders around the minute and hour hands.",
            "defaultValue": "#6f7b8c"
            }
         },
        {"secondHandColor":{
            "type":"ARRAY",
            "description":"The color of the second hand in [R,G,B, opaicity] format.",
            "defaultValue": [201, 4, 5, 0.8]
             }
        },
        {"showAMPM":{
            "type":"BOOLEAN",
            "description":"Where or not to show an AM/PM with the clock",
            "defaultValue": true
        }
        } 
    ],
    'config' : {
          'type' :
           { 'id' : 'dojo', 
             'libs' : [
                   '../resources/libs/dojo/v0.4.3/djd43.js'
               ],
               'preload' : 'if (typeof djConfig ==\'undefined\') djConfig = { parseWidgets: false, searchIds: [] };',
               'resources' : [
                 '../resources/libs/dojo/v0.4.3/src'
               ]
    }
  }
}

Same widget expressed in proposed XML markup language

<widget 
    xmlns="http://ns.openajax.org/widgets"
    xmlns:jmaki="http://something" <!-- at least one thing here is jMaki-specific -->
    name="Clock"
    libraryName="dojo"
    libraryVersion="0.4.3"
    widgetVersion='1.0'
    specVersion='1.0'       <!-- i.e., version of IDE metadata spec -->  
  >
  <description>This widget is a clock.</description>
  <icons>
    <icon src=images/dojo-clock.jpg"/>
  </icons>
  <properties>
    <property name="clockType" jsType="STRING" defaultValue="black">
      <description>The clock type.</description>
      <values>
        <value name='Plain' value='plain'>
          <description>Clock with blue background.</description>
        </value>
        <value name='Black' value='black'>
          <description>Clock with black background</description>
        <value name='Black Texture' value='value'>
          <description>Clock with black texture background.</description>
        </value>
        <value name='Gray' value='gray'>
          <description>Clock with gray background</description>
        </value>
        <value name='Gray Plastic' value='value'>
          <description>Clock with gray plastic background</description>
        </value>
      </values>
    </property>
    <property name="timeZoneOffset" jsType="number" defaultValue="0">
      <description>The time Offset."</description>
    </property>
    <property name="label" jsType="string" defaultValue="">
      <description>The label at the top of the clock.</description>
    </property>
    <property name="labelColor" jsType="string" defaultValue="#000">
      <description>The color of the label.</description>
    </property>
    <property name="topLabelColor" jsType="string" defaultValue="#efefef">
      <description>The color of the label at the top of the clock.</description>
    </property>
    <property name="handColor" jsType="string" defaultValue="#788598">
      <description>The color of the clock hand.</description>
    </property>
    <property name="handBorderColor" jsType="string"" defaultValue="#6f7b8c">
      <description>The color of the borders around the minute and hour hands.</description>
    </property>
    <property name="secondHandColor" jsType="array" defaultValue="[201, 4, 5, 0.8]">
      <description>The color of the second hand in [R,G,B, opaicity] format.</description>
    </property>
    <property name="showAMPM" jsType="boolean" defaultValue="true">
      <description>Where or not to show an AM/PM with the clock</description>
    </property>
  </properties>
  <config>
    <jmaki:libs>
      <jmaki:lib src="../resources/libs/dojo/v0.4.3/djd43.js"/>
    </jmaki:libs>
    <preload>
      if (typeof djConfig ==\'undefined\') djConfig = { parseWidgets: false, searchIds: [] };
    </preload>
    <resources>
      <resource src="../resources/libs/dojo/v0.4.3/src"/>
    </resources>
  </config>
</widget>

Proposal details

Proposed widget element

I am proposing a <widget> element that is the root element of an XML file that describes a particular widget. Note that most of the widget systems analyzed, particularly Adobe, IBM, jMaki, and W3C, included a file where the root was a <widget> XML element or a widget JavaScript object.

<widget xmlns="http://ns.openajax.org/widgets" ...attributes...>
  ...child elements...
</widget>

Explanation of subsequent sections

The following section attempts to provide a consolidate list of candidate attributes and child elements to the <widget> element. The candidates come from doing a union of the features found in the various technologies that have been examined.

Within the comments below are parenthetical remarks such as (Adobe: +++). The first part represents the technologies that included this feature. The second part represents an opinion about importance of this feature, where +++ is highest importance and - represents a negative opinion about suitability.

General metadata attributes and child elements

The following are attributes and child elements on <widget>. For example, <widget name="MyComboBox">.

<widget
  name="string"          // widget name (all: +++)
  <description>string</description> // long desciption (all: +++)
  <title>string</title>  // short desciption (IBM: ++)
  about="url"            // help page on Web (Adobe: +)
  location="url"         // widget location on Web (Adobe: -)
  author="string"        // (Adobe: +++)
  authorEmail="string"   // (IBM: +)
  libraryName="string"   // e.g., 'extjs' or 'dojo' (jMaki: ++)
  libraryVersion="#"     // e.g., '2.0.2' (none: +)
  widgetVersion="#"      // widget vers@, e.g., 1.2.3 (Adobe,jMaki: ++)
  specVersion="#"        // OpenAjax spec#, e.g., 1.2.3 (jMaki: +++)
  license="string"       // Text that describes license for widget (W3C: +)
  ... >
  ...
</widget>

JavaScript class and wrapper files

Some systems appeal more towards procedural application development will tend to treat widgets as plain old JavaScript classes. Other systems such as jMaki, with a focus on visual authoring, provide an intermediate toolkit-independent wrapper layer between the tool (e.g., the IDE or the mashup application) and the actual widgets exposed by a given Ajax library. We need to accommodate both approaches.

In Ajax library scenarios where there is a nicely defined JavaScript class for each different type of widget, we need to reference the JavaScript class for that object via a jsClass=<code> attribute on the <code><widget> element. It is assumed that there will be an API definition file for the given class within some other metadata markup.

<widget ... jsClass="dijit.form.Button" ... >
  ...
</widget ... >

Alternatively, for wrapper scenarios, the proposal is to offer optional tags <wrapperFiles> and <wrapperFile>.

Some background on existing industry practice. For its wrapper layer, jMaki uses naming conventions for its wrapper files (component.htm, component.css, component.js). Adobe proposes tags <assetfiles> and <assetfile type=css or javascript> and includes the template HTML inline using CDATA via <defaultHTML><![CDATA[. To accommodate the wrapper approach, my proposal is to go with something that merges the jMaki approach and the Adobe approach, with defaults that match jMaki. Per Adobe, the default HTML wrapper files can be included inline via CATA. There can be at most one type="html" file, but any number of CSS or JavaScript files.

<widget ... >
  ...
  <wrapperFiles>
    <wrapperFile type="html" src="component.htm"/> <!-- This is unnecessary, matches the default -->
    <wrapperFile type="css" src="component.css"/> <!-- This is unnecessary, matches the default -->
    <wrapperFile type="javascript" src="component.js"/> <!-- This is unnecessary, matches the default -->
  </wrapperFiles>
  ...
</widget ... >

Inline example:

<widget ... >
  ...
  <wrapperFiles>
    <wrapperFile type="html">
      <![CDATA[ ... ]]>
    </wrapperFile>
  </wrapperFiles>
  ...
</widget ... >

A tool (e.g., IDE or mashup application) should merge the properties defined by the wrapper files and properties defined by the underlying JavaScript class, where the wrapper files take precedence.

Metadata to help IDE populate its widget-selection palettes

IDEs often provide widget palettes. There are often multiple palettes because there might be a large number of widgets. The 'categories' attribute allows for a space-separated list of category names which a tool can use to decide onto which palette a given widget should be go. We will want to have a built-in list of category names (e.g., "basic", "mapping", "container") and an extensibility strategy (e.g., use QNames).

Icons are graphical pictures of the widget that can be used to populate widget dialogs. We should define standard sizes (e.g., 32x32).

<widget ... categories="..." >
  ...
  <icons>                // Adobe,jMaki,IBM: +++)
    <icon size="#" width="#" height="#" src="url" alt="string" />
  </icons>
...
</widget>

Widget arguments and properties

All arguments to the constructor and properties that might appear in an inspector dialog are represented as <property> elements. <property> elements can appear in two different places:

  • Inside of a <widget> element
  • Within the metadata file that contains the class definition of the JavaScript class that implements the widget.

An IDE should create a complete list of widget properties by merging together the two sets of properties.

The formal definition of the <property> element will be found on the page that defines the metadata for JavaScript APIs (http://www.openajax.org/member/wiki/IDE_API_Metadata_Strawman_Proposal ). As an executive summary, the API metadata strawman proposals starts with the <property> element from Aptana's XML format and makes the following small set of changes:

  • Aptana has a 'type' attribute that holds the JavaScript type. Some systems will want additional typing information, such as whether the value must be a positive integer or a currency amount. Therefore, I am proposing two attributes having to do with data typing, a 'jsType' attribute which holds the JavaScript type and an 'xsdType' which holds the XML Schema Datatype per that specification. Note that XML Schema is extensible and allows for custom datatypes.
  • I have added some additional attributes as needed by widgets.
  • I have taken a stab at databinding. There is a 'bindable' attribute that can take the values '1way', '2way', and 'no' and a 'bindObject' that is either a JavaScript object or a string that is the name of a JavaScript object.
  • I'm not sure about how 'visibility' works in Aptana, but I have proposed it as a hint to IDEs about whether the property should be presented to the user.

Here is an example:

<widget  ... > 
  ...
  <properties>
    <property name="clockType" jsType="" xsdType="" defaultValue="" 
              required="boolean" access="readonly" scope="" visibility="string"
              bindable="" bindObject="" >
      <description>...</description>
    </property>
  </properties>
  ...
</widget>

where:

  • name is the internal name for the field
  • description is the display text
  • jsType is the JavaScript type
  • xsdType allows for more detailed datatyping via XML Schema Datatypes [1], such as string, boolean, decimal, float, dateTime, anyURI or QName, or custom datatypes using the more advanced features.
  • defaultValue is self-explanatory
  • required is a boolean that indicates whether a value must be provided to the widget constructor
  • access is either 'readonly' or 'read-write'
  • scope is either 'static' or 'instance'
  • visibility is a hint that indicates whether the given property should appear in an inspector dialog. This is designed as an enumeration for future growth, but 'yes' and 'no' will be the only two values initially.
  • bindable: see earlier description
  • bindObject: see earlier description

Merging HTML templates, managing IDs and managing parameter substitution

There are a few scenarios about how the HTML template file is merged into the original document. Adobe shows an example with location="afterDefaultHTML". I don't have a good handle on all of the possible options, but for the time being, I propose an attribute on the <widget> element that allows this to be specified:

<widget ... templateMergeMethod="" ...>
  ...
</widget>

Some IDEs and widget systems generate automatic IDs.

Some IDEs and widget systems have parameter substitution features, where the system performs macro substitution on the HTML template during the cloning process. Adobe has @@id@@, @@selector@@, @@options@@. dijit leverages Dojo's general parameter substitution feature, which looks like this: ${title}.

The developer who puts together the metadata and wrapper HTML, CSS and JS for a given widget needs to make sure that each substitution parameter is listed among the arguments (<properties>) and that the wrappers propagate those arguments into the template properly.

Pub/sub metadata

The following information allows a tool (IDE or mashup application) to provide UI to link publishers with subscribers.

<widget ... >
  ...
  <pubsub>
    <publishesTo host="" topic=""/>
    <subscribesTo host="" topic=""/>
  ...
</widget>

Metadata about callbacks on the widget

<widget ... >
  ...
  <callbacks>
    <preload>
      ...javascript logic...
    </preload>
    <postload>
      ...javascript logic...
    </postload>
    <onChange>
      ...javascript logic...
    </onChange>
  </callbacks>
  ...
</widget>

Metadata about the library resources used to implement the widget

<widget ... >
  ...
  <config>
    <resources>
      <resource src="../resources/libs/dojo/v0.4.3/src"/>
    </resources>
  </config>
  ...
</widget>

Metadata relating to mashups and desktop-installable widgets

<widget
  website="url"          // (W3C,IBM: +++)
  width="#"              // (W3C,IBM: +++)
  height="#"             // (W3C,IBM: +++)
  preserveAspect="bool"  // (IBM: ++)
  allowScrolling="bool"  // (IBM: ++)
  accessNetwork="boolean"// (W3C,Apple: ++)
  accessPlugins="string" // (W3C,Apple: ++)
  ... >
  ...
</widget>

Supplemental notes

  • Attach point - Conspicuously absent is the lack of a metadata field for the HTML element to which this widget will be attached. My assumption is that this doesn't belong in the metadata but instead is is assumed that the tool (IDE or mashup application) will pass the domNode into the widget constructor.
  • Custom design-time UI - IBM and Adobe allow various editing dialogs to be customized. We need some hooks for that.
  • Requirements - We probably should have some metadata that talks about minimum and maximum version of particular software systems (e.g., Ajax toolkits) needed by the widget. I suggest holding off on that for now and wait until after we evaluate the Aptana <availability>, <browser>, and <deprecated> tags.
  • Dependencies - Not sure if this proposal completely satisfies the following requirement: "MUST describe in text the resources upon which the control depends"
  • Does not yet accommodate Adobe's <appliesTo>
  • Some other TODOs:
  <!-- IBM,W3C,Apple also have a persistence mechanism for data getters and setters within the widget
       and saving data on a persistence basis. Persistence is stored on server via xhr. -->
  <!-- IBM identifies the need for external objects to set/get properties from a given widget. -->
  <!-- IBM identifies the issue of managing CSS from widget and parent container(s) -->
  <!-- IBM identifies localization issue -->
  <!-- IBM identifies messaging for page to page, page to widget, and widget to widget -->
  <!-- IBM identifies the need for predefined events -->
  <!-- dijit integrates data binding via leverage of features such as dojo.data and dojo.connect -->
  <!-- dijit has a few features for container elements -->
  <!-- dijit allows for 'extension points' which pretty much are widget class methods,
       but leverages Dojo's equivalence between events and functions -->
  <!-- dijit has cross-widget features for 'value', 'disabled', 'intermediateChanges', 'tabindex',
       'focus', 'getValue', 'setDisabled', 'setValue', 'undo', and 'onChange' -->
  <!-- W3C has moveTo, moveBy, resizeTo, resizeBy APIs -->
  <!-- W3C calls for cross-widget messaging per HTML5 -->
  <!-- W3C has auto-discovery feature via link rel=widget -->
Personal tools