-
Notifications
You must be signed in to change notification settings - Fork 0
Widget Data and Metadata
This wiki page describes some aspects regarding the widget and widget metadata data structures. The main focus areas are:
- davinci/ve/widget.js
- davinci/ve/metadata.js
For background, see Widget Palette for how the Widget Palette works.
When setting up the Widget Palette, the code calls _createItem(opt)
for each widget within a loop inside of the _createPalette()
method in Palette.js.
Here is the logic in _createPalette()
that sets up the "opt" object and passes it to _createItem(opt)
:
... (foreach loop) ... var opt = { icon: dojo.moduleUrl("davinci", item.icon).uri , displayName: this._getString(item.type) || this._getString(item.name) || item.name, description: this._getString(item.type+"_description") || this._getString(item.name+"_description") || item.description || item.type, name: item.name, paletteId: this.id, type: item.type, data: item.data || {type: item.type, properties: item.properties, children: item.children}, tool: item.tool }; this._createItem(opt); ...
The _createItem()
method creates a PaletteItem object, passing the "opt" object. The various properties on the "opt" object are added to the PaletteItem object by dijit. (Dijit's widget constructor looks to see if there is an object passed into the constructor, and if so, it mixes in the properties from that argument into the widget's instance object.) The returned PaletteItem object, "node", is then passed into davinci.edit.dnd.DragSource:
_createItem: function(opt){ var node = new davinci.ve.palette.PaletteItem(opt); this.addChild(node); var ds = new davinci.edit.dnd.DragSource(node.domNode, "component", node); ... }
The constructor for davinci.edit.dnd.DragSource (davinci/edit/dnd/DragSource.js) adds the 3rd parameter (node) as a "data" property on the instance object created by the above "new" call. (i.e., the "ds" object has a "data" property which is the PaletteItem/"node" object.)
The magic of the dnd engine causes the DragSource instance object (the "ds" object above) to get added to the mouse event objects. As a result, when the onDragStart handler (in davinci/ve/Palette.js) is invoked, it receives an "event" object that has a "dragSource" property that contains the "ds" object from above. What that means is that you can find the "opt" data in the onDragStart handler by looking at:
e.dragSource.data
The onDragStart method creates a "tool" for the current widget via:
tool = new davinci.ve.tools.CreateTool(data.data);which means that CreateTool receives the "data" property from the "opt" object (see "opt" object above), which for most widgets looks like this:
{type: item.type, properties: item.properties, children: item.children}The CreateTool constructor stores the "data" in the "_data" property:
constructor: function(data){ this._data = data; ... },When the
create()
method (and then the _create()
method) is called subsequently to actually create a widget, it does so as follows:
widget = davinci.ve.widget.createWidget(this._data);which means that the
createWidget(data)
(in davinci/ve/widget/js) receives the "data" property from the "opt" object (see "opt" object above).
As mentioned above, the davinci.ve.widget.createWidget
method accepts a single argument, "data", which represents the "data" property from the "opt" object (see "opt" object above).
A key field is the "type" property, which holds values such as "dijit.form.Button". The meaning of the "type" property depends on the type of widget:
- For Dijit and Dojox widgets, the "type" is the class name for the widget.
- For "HTML widgets", the "type" consists of the string "HTML." followed by the lowercase name of an HTML element. For example, "HTML.div".
- For OpenAjax widgets, this is just a string that provides a (hopefully unique) name for the widget.
The "type" property is passed into davinci.ve.metadata.getMetadata
(in davinci/ve/metadata.js), which then finds the JSON metadata file for this widget. The type is converted into a path by converting "." into "/".
For Dojo and HTML widgets, such as "dijit.form.Button" or "HTML.div", the getMetadata() method does a dojo.xhrGet() on file "<basedir>/dijit/form/Button.json", where <basedir> is "davinci/libs/dojo_1_4". For OpenAjax widgets, the getMetadata() method invokes the OpenAjax Widget loader, which (under the hood) does an xhrGet on the *_oam.xml file. For example, for "OpenAjax.YUIColorPicker", it does an xhrGet on "<basedir>/OpenAjax/YUIColorPicker_oam.xml".
In the current code, no matter whether you load a davinci JSON file or an OAM XML file, the metadata JavaScript object is in the davinci format. The routine that converts from OAM structures into davinci structures is mapMetadataOpenAjaxToDojoy
in davinci/ve/metadata.js. (Note: we plan to switch to OAM data structures ultimately across the board. Stay tuned.)
At the end of createWidget
, the widget type and metadata are attached to the widget object:
widget.type = type; widget.metadata = metadata;
Regarding metadata.type:
- If loading a Dijit or Dojox widget, metadata.type is undefined
- If loading an HTML widget, metadata.type="html" (set at the bottom of davinci.ve.metadata.getMetadata()).
- If loading an OpenAjax widget, metadata.type="OpenAjax" (set by mapMetadataOpenAjaxToDojoy())
Maqetta (davinci) currently leverages Dojo's class hierarchy for Dijit and Dojox widgets, where there is a class for each widget. For example, for Button, the class is dijit.form.Button.
For other widget categories (i.e., HTML, OpenAjax, and this curious thing called "Object" which I don't understand yet), Maqetta creates a single class for all widgets in that category:
- For HTML widgets: davinci.ve.widget.HtmlWidget (defined in HTMLWidgetHelper.js)
- For OpenAjax widgets: davinci.ve.widget.OpenAjaxWidget (defined in OpenAjaxWidgetHelper.js)
- For Object widgets: davinci.ve.widget.ObjectWidget (defined in ObjectWidgetHelper.js)
dojo.declare("davinci.ve.widget.OpenAjaxWidget", dt._Widget, { ... isOpenAjaxWidget: true ... })Thereafter, the class is retrieved rather than recreated with each widget.
Note the isOpenAjaxWidget:true property on the widget object for OpenAjax widgets. Similarly, there is an isHTMLWidget:true property on HTML widgets and isObjectWidget:true on Object widgets. This allows the davinci logic to do conditional logic on different widget types.