One of the key benefits of the Gapjumper Web Application Framework is that it provides developers with a powerful, easy to use solution for creating and deploying custom web components[1]. Such components can range in complexity from a simple styled container to a full-blown mini-application such as a rich-text editor or spreadsheet. Use of components can help to increase productivity by facilitating code reuse (both within and across projects) and can also make sophisticated applications easier to maintain by centralizing source code.
In the Gapjumper Framework, an instance of a component is created based on the corresponding component template. A component template is a JavaScript object that defines details such as the HTML associated with a component, event handlers, initialization and destruction logic, methods and properties. Component templates are stored in the window["gapjumper.com"].controls object.
A skeleton component template is shown below. Note that not all properties are required, indeed since component templates support inheritance, an individual template may only provide a subset of the functionality required to implement a fully useable component. Within a property, method or handler definition (including the special initializer, finalizer and destroyer methods) the keyword this refers to the component instance.
The value of the extends property is an array of component templates from which the current template inherits functionality. When inheriting functionality from two or more components, properties and methods defined on later occuring components override those defined on earlier occuring components. Similarly, inheritied functionality will be overridden by functionality defined explicitly in the inheriting component. In situations where an inherited method is overriden, the callSuper method can be used to call the overriden method.
A component's initializer method is called when both it and all of its children have been inserted into the document, and after the initializers of its children and preceding siblings. Any properties of the component are set immediately prior to calling its initializer.
As implied by the terminology, an initializer is typically used to set the initial state of a component. To this end, initializers are called with a single attributes argument, this being an object giving the name/value pairs of all attributes that were specified on the component. In the case of a component like an accordion or tabBox, code executed in the initializer could safely iterate over its children (individual accordion items or tabs) to determine which one should be displayed (e.g. by examining the value of the selected property).
A component's finalizer is called after its initializer. If the component is a child of another component, then its finalizer is called after that of its parent, any preceding siblings and their descendants. Finalizers can be used to carry out any initialization logic that requires knowledge of the initial state of a component's parent.
A component's template specifies, either directly or indirectly, the HTML that is substituted for the component when the component's tag name is encountered by the Gapjumper parser. The template is described as a JavaScript object (see below) which can reference both standard HTML tags as well as other components. The position in the template where any children of the component are inserted is identified using the content tag. Abstract components, that is, components that just define properties and methods to be inherited by other components do not require a template. However, all components that are to be insertable into a document must either specify a template, or else inherit one from another component.
Properties provide a mechanism for users to influence the behavior of a component, and are also used to store internal state information. Properties are defined within the properties object as name/value pairs. The name determines the name of the property, while the value is an object that can be used to specify (i) a default value, (ii) a getter method, and (iii) a setter method. The getter method, if specified, is called whenever the property value is retrieved using the component's getProperty method. Likewise, the setter method is called whenever the property has a value assigned using the component's setProperty method. Internally a component's property values are stored in a properties array attached to the component's outermost HTML element. When implementing getters and setters, the property values should be retrieved and stored by interacting directly with the properties array. Some examples of property definiitons are shown below:
Methods encapsulate control functionality and can be called using a control's callMethod method. The first argument is a string corresponding to the name of the method to be called, while subsequent arguments correspond to the arguments of the method being called. An example method definition is shown below.
Handlers are methods that are called in response to a specified event such as a mouseclick or keypress. In the majority of cases handlers will be called when the named event occurs on the component. However, in some cases the handled event will occur on a different element (e.g. the window element in the case of the load event). In addition to common DOM Level 0 events, the event mechanism also supports the mouseenter and mouseleave events which are useful for determining whether or not the cursor is inside the component. Multiple handlers can be defined for the same event. When an event handler is called, a custom event object is passed as a parameter. This event object provides details about the event in a way which is consistent across different browsers.
In general, a component should be removed from the document using its destroy method. In addition to ensuring that any descendant controls are also removed, calling the destroy method will execute the destructor method if defined. This method can be used for carrying out custom logic such as saving data, freeing memory etc.
1. A web component is a HTML fragment with associated event handlers and logic bound to a custom tag. Attributes defined on the custom tag can be used to initialize and or modify the components' behavior.