Vexi 3.0 Changes
From Vexi
These changes have occured during development over the last few years, however Vexi2 was never officially released. This means that this document targets mainly Vexi1 users - so all changes apply to Vexi1 and some also to Vexi2. As Vexi2 was never released, the changes are not differentiated between Vexi1 and Vexi2, so we instead refer to 'old Vexi'.
There are two main types of change in the Vexi 3.0 release, herein referred to as Vexi3:
- Platform API Changes
- There are numerous platform API changes (or breakages, if you will) which are likely to cause problems for any old Vexi applications ported to the new environment
- Platform Improvements
- New features or infrastructure that offer a significant enhancement over older versions of Vexi
Contents |
Platform API Changes
VexiCode
Declare Before Use
Private variables can no longer be used before they are declared. Undeclared properties are interpreted as box properties.
Consider the following example which is invalid in Vexi3 but valid in old Vexi:
thisbox.sometrap ++= function(v) { cascade = v + p; }
var p = "bar";
someprop = "foo";
In the old core 'someprop' would be 'foobar' but in Vexi3 now it is just 'foo'.
Resources in XML
In old Vexi, XML properties which began with a '.' were interpreted as resources. Properties that began with a '$' were interpreted as box references.
- It was easy for people to mistakenly set a property to a resource
- There was no way to use namespace resources without breaking XML standards
- It mean you had to jump through hoops to use '$' or '.' in XML properties
In Vexi3 you need to prefix a ':' to all resources in XML properties.
Before:
<vexi xmlns:foo="some.foo">
<ui:box redirect="$box">
<ui:box id="box" fill=".some.img" />
<ui:box foo:template=".tmpl" />
</ui:box>
</vexi>
Vexi3:
<vexi xmlns:foo="i.am.foo">
<ui:box redirect=":$box">
<ui:box id="box" fill=":.some.img" />
<ui:box template=":foo.tmpl" />
</ui:box>
</vexi>
No Automatic Cascade
In old Vexi, traps would automatically cascade unless you returned. You had to 'return true' to break the cascade. This lead to confusing code paths. In Vexi3 cascading is explicit instead of implicit, which is also closer to the way read traps operate. Read traps are unchanged.
Before:
sometrap1 ++= function(v) {
if (v == "foo") v = v + "bar";
if (v == "bar") v = "foo" + v;
return;
}
sometrap2 ++= function() {
return "always "+cascade;
}
Vexi3:
sometrap1 ++= function(v) {
if (v == "foo") cascade = v + "bar";
if (v == "bar") cascade = "foo" + v;
return; // optional
}
// the same
sometrap2 ++= function() {
return "always "+cascade;
}
Explicit UI Namespace
You now need to set the ui namespace to use '<ui:box>'.
Before:
<vexi>
<ui:box>
<path.to.templ />
</ui:box>
</vexi>
Vexi3:
<vexi xmlns:ui="vexi://ui">
<ui:box>
<path.to.templ />
</ui:box>
</vexi>
JS Type Break
Vexi3 no longer conforms with the JS standard on the typeof operator. See the new JS types for details.
Box Properties
Grids
Before the core handled grid layout. This has been moved for efficiency reasons into the widgets.
Before:
<ui:box cols="2">
<ui:box colspan="2" />
<ui:box />
<ui:box />
</ui:box>
Vexi 3:
<vexi.layout.grid cols="2">
<ui:box colspan="2" />
<ui:box />
<ui:box />
</vexi.layout.grid>
Children
The event traps 'ChildAdded' and 'ChildRemoved' have been removed. They are superceeded by the Children meta trap.
The Children meta trap solves a number of semantic problems with the ChildAdded/ChildRemoved events which were essentially inadequate. Notably:
- The child add/remove was done before the events were fired - no way to have full control from script
- No way to know the index of a removed child at time of ChildRemoved
- No way to manipulate index of child reads on a box
- Note that Ibex has merged ChildAdded/ChildRemoved to ChildChange
Before:
// note: child already added by the time the trap is fired
ChildAdded ++= function(newchild) { ... }
// note: child already removed by the time the trap is fired
ChildRemoved ++= function(oldchild) { ... }
Vexi3:
Children ++= function(child) {
if (child) {
// ChildAdded
} else {
// ChildRemoved
}
// NOTE: the cascade is important (without it
// child is not added or removed as the trap returns)
cascade = child;
}
See also: http://vexi.blogspot.com/2007/07/children-trap.html
Window Raising
The 'toBack' and 'toFront' signal properties have been renamed 'ToBack' and 'ToFront' for consistency.
Widget Differences
The widgets have undergone wholesale changes so it is difficult to put a specific list here. The basic usage of widgets is essentially the same.
Slider / Spin
The properties 'min' and 'max' are now 'minvalue' and 'maxvalue' respectively.
Tabpane
The property 'tab' has been renamed to 'v_tab'.
Tables
Tables now have their own namespace in vexi.widget.table and, although basic manual usage should be similar.
Platform Improvements
Core
Children Meta Trap
This meta property can be trapped on for full notification of child reads and writes. It allows for complete manipulation of how children are placed in a template. See Children trap examples for more details.
Event Control
You have much more control over input events.
<ui:box id="A" layout="place">
<ui:box id="B" />
<ui:box id="C" />
</ui:box>
// prevents $B and $C from receiving Press1 events
$A._Press1 ++= function(v) { return; }
// prevents $B from receiving Press2 events
$C.Press2 ++= function(v) { return; }
// prevents $B from receiving Move/Enter/Leave events
$C.Move ++= function(v) { return; }
JUnit Tests
The core now has a test framework in place to help avoid future regressions.
Virtualization
Vexi applications can be virtualized. That is, you can launch Vexi applications from within a Vexi application. See the helper widget vexi.util.virtualize for details.
Exception Handling
Exceptions are now much more complete.
- Exceptions are recognised as their own type
- You can easily print an exception backtrace without interrupting your application
- Full support for 'finally' blocks
Example:
try {
throw "arbitrary exception";
} catch (e) {
// prints a full backtrace
vexi.log.info(e);
} finally {
// previously unsupported
}
// application resumes
Input Method Support
Interoperates with methods for using typing languages with large alphabets (primarily tested with Chinese).
JS Overhaul
New JS Engine
Vexi3 incorporates a modified and stabilized version of the Ibex JS engine.
New JS Types
In Vexi3 all main JS objects now have a corresponding typeof return:
typeof("") == "string";
typeof(true) == "boolean";
typeof(1234) == "number";
typeof({}) == "object";
typeof([]) == "array";
typeof(vexi.box) == "box";
typeof(exception) == "exception";
typeof(null) == "null";
Useful String Representations
Now all JS types convert nicely to strings for useful output. Notably resources now represent their location as a string.
Operator 'keysof'
Useful for knowing the size of a set of keys on an object without looping through them.
var k = keysof(obj);
vexi.log.info("Object "+object+" has "+k.length "+keys);
Widgets
The basic widgets are essentially the same, but every widget has seen improvement of varying degrees.
Autodocs
We now have rudimentary autodocs for the widgets.
New Widgets
Standard Widgets
- label
- numfield
- passfield
Contrib Widgets
There is now the namespace vexi.contrib which contains widgets which are not theme specific and/or fall outside of the normal widget standards, although for the most part they do interact with the widget processes (focusing, use of themed sub-widgets, etc).
- colorpicker
- datepicker
- datetime
- monthview
- timefield
Layout Widgets
Non-theme visual widgets have been moved into vexi.layout, although some still exist in the widget namespace for convenience.
- border
- cardpane
- grid
- margin
- pad
Util Widgets
Several new util widgets have been added, which accomplish several non-visual tasks
- orderedlist
- orderedarray
- virtualize
Dynamic Tables
Tables now have an API for automatic fetching of data for display large data sets. See Tables for details.
VUnit - Widget Unit Testing
The widgets have their own unit testing framework, known as VUnit. See VUnit for details.
Workflow
The workflow widget project contains templates to help implement workflow in your application in a logical way. See Workflow for details.

