Glossary:
  • EdwWidget: The root class for all widgets of this library.
  • User interface: A set of graphical elements that allow the user to interact with the application, through differents periferics like mouse, keyboard, tactil screen, etc. From now on "UI"
  • Widget: A type of element of the User Interface, in some case it may refere to a specific widget instance.

1 Introduction

The purpose of the class EdwWidget is to provide a basis on which to construct more specific and advanced widgets. It implement and define some useful funcionalities shared by all further widgets clases.
This document do not only show an overview about how to use the EdwWidget class (because EdwWidget itself is useless), but describe fundamentals to construct an user interface and to design new widgets clases on it.
Topics in this document:
  • An introduction to EdwWidget, how to use it to create full user interfaces.
  • The EdwWidget class specification.
  • How to create a new EdwWidget, requisites and technics.

2 Introduction to widgets

2.1 A widgets tree


Each widget class has a specific purpose: some of them are simple elements like buttons, texts or input box; others are containers that may hold a set of widgets instances inside them and are used to manage the user interface space, for example layouts, windows or frames.

Tree structure:

An User Interface is composed of widget objects organized in a tree structure, that is, the root widget instance is a container that hold other widget objects.

Widget localization:

In some cases, it is necesary to locate a specific instance in the tree, for example to manipualate it. For this purpose, all widget instances has a name, which is unique between all sibling widgets (child of the same parent).
Any widget may be located by his name and all his ancestor widgets, as a dot-separated list of names, beginning with the root element and ending with the required one.
As names are separated by dots (.), a name may not include this character.
Example of widget full name:
MyRootName.Frame1.myRequiredWidget
The class EdwWidget implement 2 method to manipulate his name:
  • getFullName(): Retrieve the widget full name.
  • name(...): Set or get the name of a widget.
The class EdwWidget also implement a method to localize a widget by his full name:
  • locate(...): Retrieve a widget by his full name.
See the section "The EdwWidget class" to get more information about these methodes.

2.2 User interface creation


There is 2 different ways to generate an user interface:
  • Javascript code: create and configure every widgets.
  • A full description in a file: save all the description of all widgets in a file (or files) and load it with a Javascript call to EdwWidget.load(...).

Javascript UI creation:

All widget classes has a complete set of constructors, methods and events to allow a full control with javascript. Which is useful for simple uses, for example embeded inside a web page. For large systems, the required code may grown too much and it is preferable to use external specific files.
[HTML|Javascript] Example of creating a simple UI with JS:
<noscript id="myapp">Javascript is disabled</noscript>
...
var elem = new EdwHtml(document.getElementById('myapp'));
var st = new EdwSimpleTest('widget1', elem);
st.color('blue');
st.position(new EdwVector2D(200,100));
st.size(new EdwVector2D(400,300));
				
Any html element may be converted to a widget, and it is also possible to create a widget without html element and append it whatever.

Load the UI from a file:

The second option is to load a file (or files) that contain a full description of the user interface. EdwWidget implement a class (static) method EdwWidet.load(...) that allow to read a files and construct the inteface.
By default, all widget allow to read the '.edw' format, other file format may be added or created for specific widgets. The creation of new file format descriptors for widgets is described later in the section "File format descriptor".
[HTML|Javascript] Example of creating a simple UI by loading a file:
<noscript id="myapp">Javascript is disabled</noscript>
...
var ui = null;
function callback( widget )
{
	ui = widget;
}
EdwWidget.loadCallback(callback);
var elem = new EdwHtml( document.getElementById('myapp'));
var xml = new EdwXml(new RequestFileContent("myUi.xml")).getXml());
EdwWidget.load('edw', xml, elem);
				

2.3 The '.edw' file format


The .edw file format is the default XML-based format to load user interfaces.
In an .edw file, each widget is represented as single XML element, with the widget type as tag-name and his widget specific name as name attribute:
[XML] Simplest widget representation in a .edw file
<EdwWidget name="name-example"/>

All properties of the widget are specified as a child element, with the property name as tag-name and his value set in the value attribute:
[XML] Simple .edw widget with an attribute.
<EdwWidget name="name-example">
	<active value="true"/>
</EdwWidget>
Some widgets properties require more than just one value, and in these cases, attributes names may vary:
[XML] Simple .edw widget with an attribute.
<EdwVisible name="name-example">
	<position x="50" y="75"/>
</EdwVisible>

Including sub-files in a .edw:

When an user-interface is large, the .edw file is too huge to be practical, in this case, it may be splited into sub-files, just like we usually do with code. In any part of the .edw file, an other file may be included as an include element with his url attribute pointing to the new file.
[XML] Including sub-files.
<EdwWidget name="name-example">
	<include src="./path_to_file.edw"/>
</EdwWidget>
The only restriction is that the new content (replacing the include element with the new file root element) must be a correct .edw structure.

The src path should be relative to the parent file, but this parameter is customizable by rootPath in the EdwWidget.load(...) function call.

Events in a .edw file:

A web application is not only the user interface, it require alway a portion of javascript code to describe how the interface must react to events. The .edw file allow to insert javascript code for events directly in the XML document. Every event function is specified as an event element with the attribute type to indicate the event type.
Javascript require some XML special characters, for example < or & which are operators. For this reason, it is recomended to insert the code into a CDATA section.
[XML] Event function included in the .edw file.
<EdwWidget name="name-example">
	<event type="ready">
	<![CDATA[
		// >> This is a Javascript function <<
		//     For the "ready" event of the "name-example" widget, 
		//     which is an EdwWidget instance
		alert( 'The ' + this.name() + ' widget is ready');
	]]>
	</event>
</EdwWidget>

Where to get more information:

Specific information about widgets may be found in their own documentation:
  • What elements tag-name are allowed inside every widget.
  • What attributes has every elements.
  • What event type may trigger every widget.

2.4 EdwWidget instance manipulation


EdwWidgets does not require files to manipulate them: all properties are available through Javascript method. There is different types of operations:
  • Access to widget properties: set/get
  • Access to a widget state, which is read-only.
  • Any operation that is not involved in getting or setting data.

Get/Set properties:

To avoid a huge amount of methods, getter and setter are merged into a single one: In EdwWidgets, every property is accessible through a single method with the same name that the property, if the new value is provided to the method, it will act as a setter, and in any case, it return the (maybe new) value like a getter.
anyProperty(): value
anyProperty( newValue ): value
Note: anyProperty does not really exist.

Read-only properties:

Read-only properties may be easily identified with their get method prefix:
getAnyProperty(): value
Note: anyProperty does not really exist.

Others operations:

Others operations (not involved in getting or setting properties) are accessibles through simples methods calls:
update()

delayUpdate:

With Javascript in webpages, most CPU intensive tasks are such that update any part of the HTML document, which mean compute the apparence and redraw changes.
The use of EdwWidgets (EdwVisible) usually require to perform multiples operation that may require to update the page apparence, and every change require a huge CPU usage. To avoid this problem (and optimize changes), such operations may be saved without changing the apparence and when all changes are done, the whole update is performed at once.
Some methods of EdwWidget that implies apparence changes (size or position changes), has an optional parameter delayUpdate which allow to delay the update. A novice programmer may ignore this property and his interface will update correctly every time. A more advanced programmer that want to take care about efficiency may set delayUpdate to true and update all changes at once to improve performance.
visualProperty( newValue = undefined, delayUpdate = false): value
Note: visualProperty does not really exist.

To update the apparence after using delayUpdate, EdwVisible has the method update() which perform the whole UI update.
update(): undefined

Examples:

Manipulation of EdwWidgets
var w = new EdwVisible('name');
w.position( new EdwVector2D( 10, 20), true); //delayed
w.size( new EdwVector2D( 50, 50), true);     //delayed
w.update(); // Update after a delayed setter

w.position( new EdwVector2D( 10, 20));  //not delayed and update

2.5 EdwWidget event system


Events are function called when something interesting occur to a widget: it is created, any value change, the user click on it, etc.
There is 2 ways to manage events:
  • Through the .edw file, which allow to set event functions
  • With javascript, usign EdwWidgets method to set, get or remove event functions
See the section "Events in a .edw file" to know how to manage event with files.

With javascript, the following functions allow to perform operations with event functions:
addEventListener( type: string, func: function = undefined ): boolean
hasEventListener( type: string, func: function = undefined ): boolean
removeEventListener( type: string, func: function = undefined ): boolean
The first add events, the second check if a function exist as an event listener, the third remove this function from the event listener. In any case, the result is if the operation has success.

To get the exact list of events available for a widget and the listener function specification, read the class-specific documentation.

3 EdwWidget specification

The EdwWidget class is the basis for all further widgets.
diagram
Class diagram of EdwWidget

3.1 Constructor


EdwWidget( name: string ): EdwWidget
This method is the constructor. It require 1 parameter and return the new EdwWidget object.

Parameters:

  • name: string: Is the widget instance name.

Return:

EdwWidget: The new EdwWidget object.

Throws:

This function may throw an exception if the name is not correct.

Examples:

[Javascript] Construction of a simple EdwWidget.
	var widget = new EdwWidget('my-name');

3.2 _parent(...)


_parent( parent: EdwWidget = undefined ): EdwWidget
Set or return the parent EdwWidget in the tree structure.

Parameters:

  • parent: EdwWidget = undefined: If set, set the new parent widget.

Return:

EdwWidget: The parent widget.

Throws:

This function may throw and exception if the parameter is incorrect.

Examples:

[Javascript] Example of parent().
	var widget = new EdwWidget('my-name');
	var parent = new EdwWidget('my-parent-name');
	var myParent = widget._parent(parent);;

3.3 getParent()


getParent( ): EdwWidget
Return the parent EdwWidget in the tree structure.

Parameters:

This method does not has any parameter.

Return:

EdwWidget: The parent widget.

Throws:

This function does not throw any error.

Examples:

[Javascript] Example of parent().
	var widget = new EdwWidget('my-name');
	var myParent = widget.getParent();;

3.4 name(...)


name( name: string = undefined ): string
Set or return the name of this widget.

Parameters:

  • name: string = undefined: If set, the new widget name.

Return:

string: The (maybe new) widget name.

Throws:

This may throw an error if the parameter is not valid or the name already exist for his parent widget instance.

Examples:

[Javascript] Example of name().
	var widget = new EdwWidget('my-name');
	widget.name( 'my-new-name' );
	var myName = widget.name();

3.5 getFullName()


getFullName(): string
Set or return the name of this widget.

Parameters:

This method does not has any parameter.

Return:

string: The full dot separated name locator for this widget.

Throws:

This method does not throw any error.

Examples:

[Javascript] Example of getFullName().
	var widget = new EdwWidget('my-name');
	var fullName = widget.getFullName();

3.6 getChildsList()


getChildsList( ): EdwWidget[]
Return the list of childs widget in the tree structure (an empty list for non-containers widgets).

Parameters:

This method does not has any parameter.

Return:

EdwWidget[]: The list of childs widget.

Throws:

This function does not throw any error.

Examples:

[Javascript] Example of parent().
	var widget = new EdwWidget('my-name');
	var childs = widget.getjChildsList();;

3.7 locate(...)


locate( fullName: string ): EdwWidget
Locate any widget from the tree structure by his fullName.

Parameters:

  • fullName: string: The full dot separated name locator.

Return:

EdwWidget: The matched widget or null.

Throws:

This method does not trow any error.

Examples:

[Javascript] Example of locate().
	var widget = new EdwWidget('my-name');
	var myWidget = widget.locate('my-name');
	var myWidget = widget.locate('layer.my-name'); //return null

3.8 addEventListener(...)


addEventListener( type: string, func: function ): boolean
Set a new event listener for the type event.

Parameters:

  • type: string: The type identifier of the event.
  • func: function: The function callback.

Return:

boolean: If the event is added successfully, and it was not yet set before.

Throws:

This method does not trow any error.

Examples:

[Javascript] Example of addEventListener().
	function myName_ready()
	{
		alert(this.getFullName() + ' is now ready!');
	}
	
	var widget = new EdwWidget('my-name');
	if ( !widget.addEventListener('ready', myName_ready ) )
		alert('Impossible to add this event listener, or yet set.');

3.9 hasEventListener(...)


hasEventListener( type: string, func: function ): boolean
Return if the event listener currently exist.

Parameters:

  • type: string: The type identifier of the event.
  • func: function: The function callback.

Return:

boolean: If the listener with this type and event callback exist.

Throws:

This method does not trow any error.

Examples:

[Javascript] Example of hasEventListener().
	function myName_ready()
	{
		alert(this.getFullName() + ' is now ready!');
	}
	
	var widget = new EdwWidget('my-name');
	if ( widget.hasEventListener('ready', myName_ready ) ) 
		alert('This event already exist.');
	else
		alert('This event does not exist.');

3.10 removeEventListener(...)


removeEventListener( type: string, func: function ): boolean
Remove an event listener.

Parameters:

  • type: string: The type identifier of the event.
  • func: function: The function callback.

Return:

boolean: If the event is removed successfully.

Throws:

This method does not trow any error.

Examples:

[Javascript] Example of hasEventListener().
	function myName_ready()
	{
		alert(this.getFullName() + ' is now ready!');
	}
	
	var widget = new EdwWidget('my-name');
	if ( widget.removeEventListener('ready', myName_ready ) ) 
		alert('This does not exist.');
	else
		alert('Event listener removed successfully.');

3.11 _triggerEvent(...)


_triggerEvent( eventId: string, params: mixed[] = undefined ): void
This function is protected. It trigger all 'eventId' callback function for this widget instance. Useful to implement new widgets.

Parameters:

  • eventId: string: The event identifier to trigger.
  • params: mixed[] = undefined: Any list of parameters to pass, or undefined if not required. See the event specification for more information about parameters.

Return:

This function does not return any result.

Throws:

This method does not trow any error, but may receive errors from a callback function.

Examples:

[Javascript] Example of _triggerEvent().
	this._triggerEvent('name', [this.widgetName]);

3.12 static isValidName(...)


static isValidName( name:string ): boolean
This static function return if the given string is a valid for a widget name.

Parameters:

  • name: string: The string to check.

Return:

boolean: True if the name is valid as a widget name: it does not include dots.

Throws:

This method does not trow any error.

Examples:

[Javascript] Example of isValidName().
	if ( EdwWidget.isValidName('my-Name') ) 
		alert('Al is fine.');
	else
		alert('This name is not valid for a widget name.');

3.13 static loadCallback(...)


static loadCallback( callback: function = undefined ): function
Set and get the function callback to retrieve the root widget after to call EdwWidget.load(...).

Parameters:

  • callback: function = undefined: If set, this parameter is the new callback function to retrieve the widget. If not set, this loadCallback is a getter.

Callback:

function ( widget: EdwWidget ): void
The callback function receive a custom object as this and the new root widget instance as widget.

Return:

function The (maybe new) callback function.

Throws:

This function may throw an error if the parameter is not a function.

Examples:

[Javascript] Example of loadCallback().
function callback()
{
}

<li>EdwWidget.loadCallback(callback)</li>;

3.14 static load(...)


static load( format: string, content: mixed, htmlElement: EdwHtml = undefined, rootPath: string = '', pointer: object = null ): void
Load a user interface file to generate the widget tree.

Parameters:

  • format: string: The format type identifier, for example edw.
  • content: mixed: content: the file content to load. In the case of .edw files, is an EdwDom object with the content tree.
  • htmlElement: EdwHtml = undefined: The base element to convert into the user interface. If omited, the loader will create a fragmentDocument, but all the widgets tree must be updated after to insert the fragmentDocument into the web-page to apply styles. It is recomended to use a noscript element.
  • rootPath: string = '': The url path to the root directory of the user interface, usually where is stored the main .edw file. Each include url in the interface are relative to this path.
  • pointer: object = window: The pointer this for the load callback function.

Return:

This function does not return any result.

Throws:

This method may throw different types of errors: bad arguments, incompatible browser, corrupted file, unsupported file format, unsupported widget type, etc.

Examples:

[HTML] Example of load().
<noscript id="myapp">Javascript is disabled</noscript>
[Javascript] Example of load().
var ui = null;
function callback( widget )
{
	ui = widget;
}

var elem = new EdwHtml( document.getElementById('myapp'));
var xml = new EdwXml(new RequestFileContent("myUi.xml")).getXml());
EdwWidget.loadCallback(callback);
<l>EdwWidget.load('edw', xml, elem)</l>;

3.15 static _innerLoad(...)


static _innerLoad( format: string, content: mixed, htmlElement: EdwHtml = undefined, delayUpdate: boolean = undefined ): EdwWidget
Read an XML structure to create the whole user interface. This function is protected and is required to create further widgets.

Parameters:

  • format: string: The format type identifier, for example edw.
  • content: mixed: content: the file content to load. In the case of .edw files, is an EdwDom object with the content tree.
  • htmlElement: EdwHtml = undefined: The base element to convert into the user interface. If omited, the loader will create a fragmentDocument, but all the widgets tree must be updated after to insert the fragmentDocument into the web-page to apply styles. It is recomended to use a noscript element.
  • delayUpdate: boolean = undefined: Allow to delay the update of sub-widgets in the tree structure to optimize the load. The first call should ignore it and further calls in containers widget must set it to true.

Return:

EdwWidget: The new user interface root widget.

Throws:

This method may throw different types of errors: bad arguments, incompatible browser, corrupted file, unsupported file format, unsupported widget type, etc.

Examples:

[Javascript] Example of loadCallback().
var ui = <l>EdwWidget._innerLoad('edw', content, htmlElement)</l>;

3.16 static _loadCallback(...)


static _loadCallback( req: RequestFileContent ): void
Private function to manage asynchronous request for includes in the ui file.

Parameters:

  • req: The request that call it.
  • this:object: A set of values for internal operations.

Return:

This function does not return anything.

Throws:

This method may throw different types of errors: Error loading a file, unsupported format, wrong arguments, etc.

Examples of _loadCallback().:

This function is private

3.17 static addFormat(...)


static addFormat( format: string, widgetName: string, paths: string{}, version: string, converter: function ): boolean
Add support for a new per of widget class and file format.
The converter function convert the file content to an EdwDom object which is readable by _readDomXml functions

Parameters:

  • format: string: The format type identifier to which add a widget support, for example edw.
  • widgetName: string: The name of the widget class to which add support for a new file format.
  • paths: string{}: An object of strings: prefix are strings that identify all required values for a widget instance, defined by the widget class specification. The value is an xpath string to match in the EdwDom file content the required data.
  • version: string: Define a file format version, with allow the converter function to check the file loaded against the required in order to throw an error if required.
  • converter: function: A function to convert the file content into an EdwDom object which is readable by each _readDomXml functions. If not required (becouse the file format is XML based), this function may be null.

Return:

boolean: True if the format support is added correctly, false if any path is missing.

Throws:

This method throw an error if any parameter is incorrect.

Examples:

This method may throw different types of errors: bad arguments, incompatible browser, corrupted file, unsupported file format, unsupported widget type, etc.
[Javascript] Example of addFormat().
assert( EdwWidget.addFormat
(
	'edw',               // Format identifier
	'EdwWidget',         // Widget name
	{                    // Path list
		'name'  : '@name',           // The name of the widget
		'active': 'active/@value',   // If the widget is active
		'event' : 'event',           // Get all event for this widget
		'event-type': '@type'        // Get the type of an event
	}, 
	'1.0',               // Version
	null                 //Converter is not required as edw is a xml format
), 'This format description is incomplet');

3.18 static testFormat(...)


static testFormat( format: string ): boolean
Test if the given format is supported by EdwWidget (only EdwWidget, not inherited widgets). All widget classes must override this method.

Parameters:

  • format: string: The file format identifier, for example edw.

Return:

boolean: True if the file format is supported by EdwWidget.

Throws:

This method does not trow any error.

Examples:

[Javascript] Example of testFormat().
	var fileFormat = 'edw';
	if ( EdwWidget.testFormat( fileFormat ))
		alert(fileFormat + ' is supported.');
	else
		alert(fileFormat + ' is not supported.');

3.19 _readDomXml(...)


static _readDomXml( format: string, dom: EdwDom, htmlElement: EdwHtml, widget: EdwWidget = undefined, delayUpdate: boolean = undefined ): EdwWidget
Load the EdwDom structure to create and configure the widget tree.

Parameters:

  • format: string: The file format identifier, to read the EdwDom structure, for example edw.
  • dom: EdwDom: The file content, converted to a dom structure.
  • htmlElement: The EdwHtml element to convert into the new user interface. May be undefined, in which case the user interface is created on a fragment-document.
  • widget: EdwWidget: For recursivity, this is the widget to configure.
  • delayUpdate: boolean = undefined: When creating a big widget instance tree, this parameter allow to update the whole structure at once.

Return:

EdwWidget: The widget instance tree.

Throws:

This method may throw different types of errors: bad arguments, incompatible browser, corrupted file, unsupported file format, unsupported widget type, etc.

Examples:

[Javascript] Example of _readDomXml().
// This method should only be used inside EdwWidget.load(..) 
// and _readDomXml functions.

var widget = EdwWidget._readDomXml(format, xml, htmlElement, undefined, false);

3.20 Events specification


This section is a specification of events that may be triggered by an EdwWidget, and functions declaration of every event listener.
In addition to every function parameter, all callback function has access to the widget itself through the this pointer.

ready:

Triggered when the EdwWidget just finished to be configure by loading a file.
function()

parent:

Triggered when the parent widget is changed to another one.
function(newParentWidget: EdwWidget)

active:

Triggered when the activation value is changed.
function(newActiveValue: boolean)

name:

Triggered when the widget name is changed.
function(newNameValue: string)

3.21 DTD of .edw file format for EdwWidgets


This section describe the file format edw for EdwWidgets.
[DTD] EdwWidget .edw dtd
<!DOCTYPE EdwWidget [
	<!ELEMENT EdwWidget (active?, event*)>
	<!ELEMENT event (#PCDATA)>

	<!ATTLIST EdwWidget name CDATA #REQUIRED> 
	<!ATTLIST event type CDATA #REQUIRED>
]> 

Description of element:

  • event = (none): Every event listener

Description of attributes:

  • EdwWidget:name: The name of the widget.
  • active:value: true or false, to set the widget activation.

Description of contents:

  • event: The event listener code.

4 New widget design

This section describe deep theory to design a new widget class. This explanation include only generic rules for all widgets, consider that more specific widget may have their own mechanism and rules.

4.1 Construction mechanism


The constructor:

Each widget has his own Javascript constructor that allow to create an instance of it. This constructor is the basis to create new object even loading a new user interface with an edw file description.
To standarize the library and make usage and design easier, the constructor must receive as few parameters as possible, commonly just the widget name property, the base html element and the delayUpdate parameter. All other properties must be set to a default value that the user may change after the creation.

Formats:

The EdwWidget loader allow to construct an user interface from a file with a correct description in a specific file format. All widget must support to at least the edw file format, but may also allow other formats.
To be able to create and include new formats without modifying all classes, EdwWidget include a set of functions and data to add new file formats. The only requisite it that Javascript must be able to load this file and convert it to a readable XML document.

static load(...):

To load a file into a new user interface, the function EdwWidget.load must be called:
static load( format: string, content: mixed, htmlElement: EdwHtml = undefined, rootPath: string = '', pointer: object = null ): void
See the class specification to see the full description. In this section it is important to understan how it work.
class internal behavior
load internal behavior
This function call a convertion function that read the file and convert it into a XML DOM structure. In the case of XML file formats (like edw) this step is not necesary and is skipped. After that, it request all includes sub-files and call recursively a specific loader for each widget in the document, which construct his content. The resulted UI is returned to a callback function that may be specified with EdwWidget.loadCallback(...). These functions are static for all widgets and does not require to be changed or ovewrided.

The widget name register:

In the XML DOM structure, a widget is described as an element with a tag name, which is a string. The constructor of a widget is a function and his name is not accessible from the code. The function EdwWidget.load must be able to found the constructor for the specific XML element tag name in the document.
When the library is loaded, all widgets must register their name in: EdwWidget._widgetClases
[Javascript] Widget name register (example for EdwSimpleTest)
if (undefined===EdwWidget._widgetClases)
{
	EdwWidget._widgetClases={};
}
EdwWidget._widgetClases['EdwSimpleTest']=EdwSimpleTest;
This allow further code to get the constructor for a given widget name.

widget._readDomXml(...):

Each widget class must implement his own version of the static function:
static _readDomXml( format: string, dom: EdwDom, htmlElement: EdwHtml, widget: EdwWidget = undefined, delayUpdate: boolean = undefined ): EdwWidget
See the class specification for a full description. This function perform 3 major tasks: call the constructor, set recursively all parameters and call the ready event.

readDomXml behavior
_readDomXml internal behavior
EdwWidget.load (or his private EdwWidget._loadCallback(...)) call the correct widget _readDomXml, which first read basic properties from the XML DOM and create the widget calling the constructor.
After that, it call recursively his parent _readDomXml to set parent properties. Parent calls know that they must not create the new widget because they receive it through the fourth parameter (widgetObj), which is undefined for the first call.
It read all values from the XML DOM by evaluating xpath for this format, and set these value for the widget.
In the case of container widgets, it may call to EdwWidget.innerLoad(...) to generate the inner widget and set as child widget.
Finally, it set the widget to visible (if required), and call the "ready" event listeners.

Visibility of the widget until it is ready:

The widget must be hidden until it is ready, to avoid artefact during the load. The _readDomXml function must hide the widget before the constructor call create it all hidden and show it just before returning. The constructor itself must not hide the widget, because the widget must be ready to use just after construction without any update, anyway the programmer may if he want hide it himself.

4.2 File format descriptor


This section explain file format supports.

addFormat(...):

For every per of widget and format, a call to the following function must be performed:
static addFormat( format: string, widgetName: string, paths: object, 
    version: string, converter: function): boolean
See the EdwWidget specification for more detailed information.

This call save all data required by EdwWidget.load() to read this format and convert it into a correct user interface. Additionally, it is recomended to include these function call into an assert check, to throw an error if the call is incorrect (usually because a xpath string is missing).
File format description must be saved into an external file, which allow to be loaded separately and does not interfer with the widget class code.
addFormat comunication diagram
Communication diagram
To implement a new widget, at least the .edw file format must be added.
addFormat activity diagram
Activity diagram

testFormat(...):

The function addFormat check the file format description before to return true, this is done by calling the function testFormat:
static testFormat( format: string ): boolean
This static function must be overrided by every widget class, and it must test the whole set of parameter required to construct the new instance.

[Javascript] Function testFormat, example for EdwWidget.
EdwWidget.testFormat = function ( format)
{
	if (!EdwWidget._format || !EdwWidget._format[format] || 
		!EdwWidget._format[format].widget['EdwWidget']) return false;
		
	var paths = EdwWidget._format[format].widget['EdwWidget'];
	if (!paths['name'])   return false;
	if (!paths['event']) return false;
	if (!paths['event-type']) return false;
	return true;
}

4.3 Localization mechanism


The localizatin mechanism allow to retrieve any widget of the user interface. This section explain how it work and what every widget must implement for it.
There are two functions for localization: getFullName() that retrieve the full, dot separated name for the current widget. And locate(...) that retrieve a widget for a full name. None of them require to be overrided in a new widget class. See the EdwWidget specification for more info about these function and their use.

getFullName():

getFullName(): string

locate(...):

locate( fullName: string ): EdwWidget
The locate method check if the fullName match his name or any of his descendent widgets:
locate activity diagram
Activity diagram

4.4 Event system


For events, EdwWidget implement required methods:
  • addEventListener(...)
  • removeEventListener(...)
  • hasEventListener(...)
(See EdwWidgte class specification for more details).

All other widgets class must perform two operation to allow new specific events: Register new event identifier, and trigger every event when required in the code.

Register a new event for a new widget class:

In the constructor of the widget, add a new row to this.event with the identifier of the event as key and an empty array as value. This data structure is used to store callback function so it is not an innecesary memory use.
this.event['mynewevent']= [];
An event identifier must contain only lower case letters:
/[a-z]+/

Trigger an event in the class code:

In any part of the widget class code, to trigger an event, just call the _triggerEvent(...) method (See the EdwWidget class specification for more information).
this._triggerEvent('mynewevent');

4.5 Requisite for a new widget


In order to be accepted as a widget, a new class must follow some rules for quality and homogeneity.

Programming style guide:

Programming style guide establish a set of rules to allow homogeneity in the code and to avoid simple errors. This project (and all his code) follow 2 programming style guide:
  • A General purpose programming guide: which is shared for all languages.
  • A Javascript specific programming guide: with rules that have only sence for this language.

5 Documents:

At least 5 documents are required for every widget:
  • Widget class: A .js file with the well terminated code of the widget.
  • Format descriptor: A .js file with the format descriptor of at least "edw".
  • Test set: An HTML file that fully, automatically and deeply test all features of the widget.
  • Documentation: An XML document that follow this document.dtd structure with a full and useful description of the widget. (take this document as example). For most widget, only the class specification is required.
  • Default CSS style: A CSS style sheet for default aparence, that must match the same visual style than others widgets.

Name of the widget:

The new widget must has a name, for the class identifier and for XML elements. A name is a concatenation of "Edw" with a descriptive name.
Example of widget name.
EdwMyWidgetName

Summary of tecnical rules:

A widget must:
  • Implement his own _readDomXml function, which must construct the widget hidden and show it if required when it is finished.
  • Register his name at loading
  • Implement testFormat(...)
  • Override getChildsList() if required (containers).
  • Follow both programming style guide.
  • Include 5 documents: the class code, the format descriptor, the test set, documentation and default CSS style.
  • Follow the naming rule for widgets
  • Take as few parameters as possible for the constructor.
  • Re-use code when possible
  • Set required styles of the widget as element style, to avoid conflicts with style sheets