summaryrefslogtreecommitdiffstatshomepage
path: root/includes/js/dojox/wire
diff options
context:
space:
mode:
Diffstat (limited to 'includes/js/dojox/wire')
-rw-r--r--includes/js/dojox/wire/CompositeWire.js103
-rw-r--r--includes/js/dojox/wire/DataWire.js179
-rw-r--r--includes/js/dojox/wire/README53
-rw-r--r--includes/js/dojox/wire/TableAdapter.js88
-rw-r--r--includes/js/dojox/wire/TextAdapter.js88
-rw-r--r--includes/js/dojox/wire/TreeAdapter.js188
-rw-r--r--includes/js/dojox/wire/Wire.js336
-rw-r--r--includes/js/dojox/wire/XmlWire.js244
-rw-r--r--includes/js/dojox/wire/_base.js195
-rw-r--r--includes/js/dojox/wire/demos/TableContainer.css25
-rw-r--r--includes/js/dojox/wire/demos/TableContainer.css.commented.css30
-rw-r--r--includes/js/dojox/wire/demos/TableContainer.js68
-rw-r--r--includes/js/dojox/wire/demos/WidgetRepeater.js33
-rw-r--r--includes/js/dojox/wire/demos/markup/countries.json43
-rw-r--r--includes/js/dojox/wire/demos/markup/demo_ActionChaining.html108
-rw-r--r--includes/js/dojox/wire/demos/markup/demo_ActionWiring.html142
-rw-r--r--includes/js/dojox/wire/demos/markup/demo_BasicChildWire.html78
-rw-r--r--includes/js/dojox/wire/demos/markup/demo_BasicColumnWiring.html90
-rw-r--r--includes/js/dojox/wire/demos/markup/demo_ConditionalActions.html221
-rw-r--r--includes/js/dojox/wire/demos/markup/demo_FlickrStoreWire.html281
-rw-r--r--includes/js/dojox/wire/demos/markup/demo_TopicWiring.html78
-rw-r--r--includes/js/dojox/wire/demos/markup/flickrDemo.css29
-rw-r--r--includes/js/dojox/wire/demos/markup/flickrDemo.css.commented.css35
-rw-r--r--includes/js/dojox/wire/demos/markup/states.json56
-rw-r--r--includes/js/dojox/wire/ml/Action.js225
-rw-r--r--includes/js/dojox/wire/ml/Data.js143
-rw-r--r--includes/js/dojox/wire/ml/DataStore.js116
-rw-r--r--includes/js/dojox/wire/ml/Invocation.js171
-rw-r--r--includes/js/dojox/wire/ml/Service.js340
-rw-r--r--includes/js/dojox/wire/ml/Transfer.js359
-rw-r--r--includes/js/dojox/wire/ml/util.js295
-rw-r--r--includes/js/dojox/wire/tests/markup/Action.html147
-rw-r--r--includes/js/dojox/wire/tests/markup/Data.html105
-rw-r--r--includes/js/dojox/wire/tests/markup/DataStore.html66
-rw-r--r--includes/js/dojox/wire/tests/markup/DataStore.xml18
-rw-r--r--includes/js/dojox/wire/tests/markup/Invocation.html53
-rw-r--r--includes/js/dojox/wire/tests/markup/Service.html84
-rw-r--r--includes/js/dojox/wire/tests/markup/Service/JSON.smd11
-rw-r--r--includes/js/dojox/wire/tests/markup/Service/XML.smd11
-rw-r--r--includes/js/dojox/wire/tests/markup/Service/a.json5
-rw-r--r--includes/js/dojox/wire/tests/markup/Service/a.xml5
-rw-r--r--includes/js/dojox/wire/tests/markup/Transfer.html157
-rw-r--r--includes/js/dojox/wire/tests/module.js13
-rw-r--r--includes/js/dojox/wire/tests/programmatic/CompositeWire.js51
-rw-r--r--includes/js/dojox/wire/tests/programmatic/ConverterDynamic.js12
-rw-r--r--includes/js/dojox/wire/tests/programmatic/DataWire.js25
-rw-r--r--includes/js/dojox/wire/tests/programmatic/TableAdapter.js24
-rw-r--r--includes/js/dojox/wire/tests/programmatic/TextAdapter.js25
-rw-r--r--includes/js/dojox/wire/tests/programmatic/TreeAdapter.js29
-rw-r--r--includes/js/dojox/wire/tests/programmatic/Wire.js123
-rw-r--r--includes/js/dojox/wire/tests/programmatic/XmlWire.js32
-rw-r--r--includes/js/dojox/wire/tests/programmatic/_base.js111
-rw-r--r--includes/js/dojox/wire/tests/runTests.html9
-rw-r--r--includes/js/dojox/wire/tests/wire.js18
-rw-r--r--includes/js/dojox/wire/tests/wireml.js18
55 files changed, 5592 insertions, 0 deletions
diff --git a/includes/js/dojox/wire/CompositeWire.js b/includes/js/dojox/wire/CompositeWire.js
new file mode 100644
index 0000000..7d1015d
--- /dev/null
+++ b/includes/js/dojox/wire/CompositeWire.js
@@ -0,0 +1,103 @@
+if(!dojo._hasResource["dojox.wire.CompositeWire"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.wire.CompositeWire"] = true;
+dojo.provide("dojox.wire.CompositeWire");
+
+dojo.require("dojox.wire._base");
+dojo.require("dojox.wire.Wire");
+
+dojo.declare("dojox.wire.CompositeWire", dojox.wire.Wire, {
+ // summary:
+ // A Wire for composite values in object or array
+ // description:
+ // This class has multiple child Wires for object properties or array
+ // elements.
+ // When an object with Wires is specified to 'children' property, they
+ // are used to get or set an object with property values.
+ // When an array of Wiares is specified to 'children' property, they
+ // are used to get or set an array with element values.
+
+ _wireClass: "dojox.wire.CompositeWire",
+
+ constructor: function(/*Object*/args){
+ // summary:
+ // Initialize properties
+ // description:
+ // If object properties or array elements specified in 'children'
+ // property are not Wires, Wires are created from them as
+ // arguments, with 'parent' property set to this Wire instance.
+ // args:
+ // Arguments to initialize properties
+ // children:
+ // An object or array containing child Wires
+ this._initializeChildren(this.children);
+ },
+ _getValue: function(/*Object||Array*/object){
+ // summary:
+ // Return an object with property values or an array with element
+ // values
+ // description:
+ // This method calls getValue() method of the child Wires with
+ // 'object' argument and returns an object with the values as
+ // properties or an arary of the values as elements.
+ // object:
+ // A root object
+ // returns:
+ // An object or array with values
+ if(!object || !this.children){
+ return object; //Object||Array
+ }
+
+ var value = (dojo.isArray(this.children) ? [] : {}); // array or object
+ for(var c in this.children){
+ value[c] = this.children[c].getValue(object);
+ }
+ return value;//Object||Array
+ },
+
+ _setValue: function(/*Object||Array*/object, /*Object||Array*/value){
+ // summary:
+ // Set an object properties or an array elements to an object
+ // desription:
+ // This method calls setValues() method of the child Wires with
+ // a corresponding property or element in 'value' argument and
+ // 'object' argument.
+ // object:
+ // A root object
+ // value:
+ // An object or array with values to set
+ // returns:
+ // 'object'
+ if(!object || !this.children){
+ return object; //Object||Array
+ }
+
+ for(var c in this.children){
+ this.children[c].setValue(value[c], object);
+ }
+ return object; //Object||Array
+ },
+
+ _initializeChildren: function(/*Object||Array*/children){
+ // summary:
+ // Initialize child Wires
+ // description:
+ // If object properties or array elements specified in 'children'
+ // argument are not Wires, Wires are created from them as
+ // arguments, with 'parent' property set to this Wire instance.
+ // children:
+ // An object or array containing child Wires
+ if(!children){
+ return; //undefined
+ }
+
+ for(var c in children){
+ var child = children[c];
+ child.parent = this;
+ if(!dojox.wire.isWire(child)){
+ children[c] = dojox.wire.create(child);
+ }
+ }
+ }
+});
+
+}
diff --git a/includes/js/dojox/wire/DataWire.js b/includes/js/dojox/wire/DataWire.js
new file mode 100644
index 0000000..ecb6223
--- /dev/null
+++ b/includes/js/dojox/wire/DataWire.js
@@ -0,0 +1,179 @@
+if(!dojo._hasResource["dojox.wire.DataWire"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.wire.DataWire"] = true;
+dojo.provide("dojox.wire.DataWire");
+
+dojo.require("dojox.wire.Wire");
+
+dojo.declare("dojox.wire.DataWire", dojox.wire.Wire, {
+ // summary:
+ // A Wire for item attributes of data stores
+ // description:
+ // This class accesses item attributes of data stores with a dotted
+ // notation of attribute names specified to 'attribute' property,
+ // using data APIs of a data store specified to 'dataStore' property.
+ // The root object for this class must be an item of the data store.
+ // Intermediate attribute names in the dotted notation specify
+ // attributes for child items, which are used for repeated calls to
+ // data APIs until reached to a descendant attribute.
+ // Attribute names may have an array index, such as "a[0]", to
+ // identify an array element of the attribute value.
+
+ _wireClass: "dojox.wire.DataWire",
+
+ constructor: function(/*Object*/args){
+ // summary:
+ // Initialize properties
+ // description:
+ // If 'dataStore' property is not specified, but 'parent' property
+ // is specified, 'dataStore' property is copied from the parent.
+ // args:
+ // Arguments to initialize properties
+ // dataStore:
+ // A data store
+ // attribute:
+ // A dotted notation to a descendant attribute
+ if(!this.dataStore && this.parent){
+ this.dataStore = this.parent.dataStore;
+ }
+ },
+ _getValue: function(/*Object*/object){
+ // summary:
+ // Return an attribute value of an item
+ // description:
+ // This method uses a root item passed in 'object' argument and
+ // 'attribute' property to call getValue() method of
+ // 'dataStore'.
+ // If an attribute name have an array suffix ("[]"), getValues()
+ // method is called, instead.
+ // If an index is specified in the array suffix, an array element
+ // for the index is returned, instead of the array itself.
+ // object:
+ // A root item
+ // returns:
+ // A value found, otherwise 'undefined'
+ if(!object || !this.attribute || !this.dataStore){
+ return object; //Object
+ }
+
+ var value = object;
+ var list = this.attribute.split('.');
+ for(var i in list){
+ value = this._getAttributeValue(value, list[i]);
+ if(!value){
+ return undefined; //undefined
+ }
+ }
+ return value; //anything
+ },
+
+ _setValue: function(/*Object*/object, /*anything*/value){
+ // summary:
+ // Set an attribute value to an item
+ // description:
+ // This method uses a root item passed in 'object' argument and
+ // 'attribute' property to identify an item.
+ // Then, setValue() method of 'dataStore' is called with a leaf
+ // attribute name and 'value' argument.
+ // If an attribute name have an array suffix ("[]"), setValues()
+ // method is called, instead.
+ // If an index is specified in the array suffix, an array element
+ // for the index is set to 'value', instead of the array itself.
+ // object:
+ // A root item
+ // value:
+ // A value to set
+ // returns:
+ // 'object', or 'undefined' for invalid attribute
+ if(!object || !this.attribute || !this.dataStore){
+ return object; //Object
+ }
+
+ var item = object;
+ var list = this.attribute.split('.');
+ var last = list.length - 1;
+ for(var i = 0; i < last; i++){
+ item = this._getAttributeValue(item, list[i]);
+ if(!item){
+ return undefined; //undefined
+ }
+ }
+ this._setAttributeValue(item, list[last], value);
+ return object; //Object
+ },
+
+ _getAttributeValue: function(/*Object*/item, /*String*/attribute){
+ // summary:
+ // Return an attribute value of an item
+ // description:
+ // This method uses an item passed in 'item' argument and
+ // 'attribute' argument to call getValue() method of 'dataStore'.
+ // If an attribute name have an array suffix ("[]"), getValues()
+ // method is called, instead.
+ // If an index is specified in the array suffix, an array element
+ // for the index is returned, instead of the array itself.
+ // item:
+ // An item
+ // attribute
+ // An attribute name
+ // returns:
+ // A value found, otherwise 'undefined'
+ var value = undefined;
+ var i1 = attribute.indexOf('[');
+ if(i1 >= 0){
+ var i2 = attribute.indexOf(']');
+ var index = attribute.substring(i1 + 1, i2);
+ attribute = attribute.substring(0, i1);
+ var array = this.dataStore.getValues(item, attribute);
+ if(array){
+ if(!index){ // return array for "attribute[]"
+ value = array;
+ }else{
+ value = array[index];
+ }
+ }
+ }else{
+ value = this.dataStore.getValue(item, attribute);
+ }
+ return value; //anything
+ },
+
+ _setAttributeValue: function(/*Object*/item, /*String*/attribute, /*anything*/value){
+ // summary:
+ // Set an attribute value to an item
+ // description:
+ // This method uses an item passed in 'item' argument and
+ // 'attribute' argument to call setValue() method of 'dataStore'
+ // with 'value' argument.
+ // If an attribute name have an array suffix ("[]"), setValues()
+ // method is called, instead.
+ // If an index is specified in the array suffix, an array element
+ // for the index is set to 'value', instead of the array itself.
+ // item:
+ // An item
+ // attribute:
+ // An attribute name
+ // value:
+ // A value to set
+ var i1 = attribute.indexOf('[');
+ if(i1 >= 0){
+ var i2 = attribute.indexOf(']');
+ var index = attribute.substring(i1 + 1, i2);
+ attribute = attribute.substring(0, i1);
+ var array = null;
+ if(!index){ // replace whole array for "attribute[]"
+ array = value;
+ }else{
+ array = this.dataStore.getValues(item, attribute);
+ if(!array){
+ array = [];
+ }
+ array[index] = value;
+ }
+ this.dataStore.setValues(item, attribute, array);
+ }else{
+ this.dataStore.setValue(item, attribute, value);
+ }
+ }
+});
+
+}
diff --git a/includes/js/dojox/wire/README b/includes/js/dojox/wire/README
new file mode 100644
index 0000000..8f3f831
--- /dev/null
+++ b/includes/js/dojox/wire/README
@@ -0,0 +1,53 @@
+-------------------------------------------------------------------------------
+DojoX Wire
+-------------------------------------------------------------------------------
+Version 1.0
+Release date: 05/29/2007
+-------------------------------------------------------------------------------
+Project state: stable
+-------------------------------------------------------------------------------
+Project authors
+ Jared Jurkiewicz (jared.jurkiewicz@gmail.com)
+-------------------------------------------------------------------------------
+Project description
+
+The DojoX Wire project is a set of functions that build a generic data binding
+and service invocation library to simplify how data values across a wide
+variety of widget and non-widget JavaScript constructs are accessed, updated,
+and passed to and from services. It also provides a set of widgets
+within the dojox.wire.ml package to allow for declarative data binding
+definitions in addition to the programmatic APIs.
+
+In essense, this project is an API to provide a simplified way of doing MVC
+patterns in the client.
+
+-------------------------------------------------------------------------------
+Dependencies:
+
+DojoX Wire has dependencies on core dojo, the dijit widget system (for classes
+in the dojox.wire.ml package), dojox.data, and the D.O.H. unit test framework.
+-------------------------------------------------------------------------------
+Documentation:
+
+See the Dojo API tool (http://dojotoolkit.org/api)
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/wire.js
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/wire/*
+
+Install into the following directory structure:
+/dojox/wire/
+
+...which should be at the same level as your Dojo checkout.
+
+It should look like:
+/dojox/wire.js
+/dojox/wire/*
+
+Require in dojox.wire for all baseline functions (dojox.wire.connect,
+dojox.wire.register, etc). For specific Wire classes,
+require in the appropriate dojox.wire.<Class>.
+-------------------------------------------------------------------------------
+
diff --git a/includes/js/dojox/wire/TableAdapter.js b/includes/js/dojox/wire/TableAdapter.js
new file mode 100644
index 0000000..16a5280
--- /dev/null
+++ b/includes/js/dojox/wire/TableAdapter.js
@@ -0,0 +1,88 @@
+if(!dojo._hasResource["dojox.wire.TableAdapter"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.wire.TableAdapter"] = true;
+dojo.provide("dojox.wire.TableAdapter");
+
+dojo.require("dojox.wire.CompositeWire");
+
+dojo.declare("dojox.wire.TableAdapter", dojox.wire.CompositeWire, {
+ // summary:
+ // A composite Wire for table rows
+ // description:
+ // This class has multiple child Wires for object properties or array
+ // elements of a table row.
+ // The root object for this class must be an array.
+ // When an object with Wires is specified to 'columns' property, they
+ // are used to get a row object with property values.
+ // When an array of Wires is specified to 'columns' property, they
+ // are used to get a row array with element values.
+ // The row values are returned in an array.
+ // This class only supports getValue(), but not setValue().
+
+ _wireClass: "dojox.wire.TableAdapter",
+
+ constructor: function(/*Object*/args){
+ // summary:
+ // Initialize properties
+ // description:
+ // If object properties or array elements specified in 'columns'
+ // property are not Wires, Wires are created from them as
+ // arguments, with 'parent' property set to this Wire instance.
+ // args:
+ // Arguments to initialize properties
+ // columns:
+ // An object or array containing child Wires for column values
+ this._initializeChildren(this.columns);
+ },
+
+ _getValue: function(/*Array*/object){
+ // summary:
+ // Return an array of table row value (object or array)
+ // description:
+ // This method iterates over an array specified to 'object'
+ // argument and calls getValue() method of the child Wires with
+ // each element of the array to get a row object or array.
+ // Finally, an array with the row objects or arrays are retuned.
+ // object:
+ // A root array
+ // returns:
+ // An array of table row value
+ if(!object || !this.columns){
+ return object; //Array
+ }
+
+ var array = object;
+ if(!dojo.isArray(array)){
+ array = [array];
+ }
+
+ var rows = [];
+ for(var i in array){
+ var row = this._getRow(array[i]);
+ rows.push(row);
+ }
+ return rows; //Array
+ },
+
+ _setValue: function(/*Array*/object, /*Array*/value){
+ // summary:
+ // Not supported
+ throw new Error("Unsupported API: " + this._wireClass + "._setValue");
+ },
+
+ _getRow: function(/*Object||Array*/object){
+ // summary:
+ // Return an array or object for a table row
+ // description:
+ // This method calls getValue() method of the child Wires to
+ // create a row object or array.
+ // returns:
+ // An array or object for a table row
+ var row = (dojo.isArray(this.columns) ? [] : {}); // array or object
+ for(var c in this.columns){
+ row[c] = this.columns[c].getValue(object);
+ }
+ return row; //Array||Object
+ }
+});
+
+}
diff --git a/includes/js/dojox/wire/TextAdapter.js b/includes/js/dojox/wire/TextAdapter.js
new file mode 100644
index 0000000..36e7f1d
--- /dev/null
+++ b/includes/js/dojox/wire/TextAdapter.js
@@ -0,0 +1,88 @@
+if(!dojo._hasResource["dojox.wire.TextAdapter"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.wire.TextAdapter"] = true;
+dojo.provide("dojox.wire.TextAdapter");
+
+dojo.require("dojox.wire.CompositeWire");
+
+dojo.declare("dojox.wire.TextAdapter", dojox.wire.CompositeWire, {
+ // summary:
+ // A composite Wire for a concatenated text
+ // description:
+ // This class has multiple child Wires for text segment values.
+ // Wires in 'segments' property are used to get text segments and
+ // values are concatenated with an optional delimiter string specified
+ // to 'delimiter' property.
+
+ _wireClass: "dojox.wire.TextAdapter",
+
+ constructor: function(/*Object*/args){
+ // summary:
+ // Initialize properties
+ // description:
+ // If array elements specified in 'segments' are not Wires, Wires
+ // are created from them as arguments, with 'parent' property set
+ // to this Wire instance.
+ // args:
+ // Arguments to initialize properties
+ // segments:
+ // An array containing child Wires for text segment values
+ // delimiter:
+ // A delimiter string
+ this._initializeChildren(this.segments);
+ if(!this.delimiter){
+ this.delimiter = "";
+ }
+ },
+
+ _getValue: function(/*Object||Array*/object){
+ // summary:
+ // Return a concatenated text
+ // description:
+ // This method calls getValue() method of the child Wires wuth
+ // 'object' argument and concatenate the values with 'delimiter'
+ // property to return.
+ // arg:
+ // A root object
+ // returns:
+ // A concatinated text
+ if(!object || !this.segments){
+ return object; //Object||Array
+ }
+
+ var text = "";
+ for(var i in this.segments){
+ var segment = this.segments[i].getValue(object);
+ text = this._addSegment(text, segment);
+ }
+ return text; //String
+ },
+
+ _setValue: function(/*Object||Array*/object, /*String*/value){
+ // summary:
+ // Not supported
+ throw new Error("Unsupported API: " + this._wireClass + "._setValue");
+ },
+
+ _addSegment: function(/*String*/text, /*String*/segment){
+ // summary:
+ // Return a concatenated text
+ // description:
+ // This method add a text segment specified to 'segment' argument
+ // to a base text specified to 'text', with 'delimiter' property.
+ // text:
+ // A base text
+ // segment:
+ // A text segment to add
+ // returns:
+ // A concatinated text
+ if(!segment){
+ return text; //String
+ }else if(!text){
+ return segment; //String
+ }else{
+ return text + this.delimiter + segment; //String
+ }
+ }
+});
+
+}
diff --git a/includes/js/dojox/wire/TreeAdapter.js b/includes/js/dojox/wire/TreeAdapter.js
new file mode 100644
index 0000000..b9b16bf
--- /dev/null
+++ b/includes/js/dojox/wire/TreeAdapter.js
@@ -0,0 +1,188 @@
+if(!dojo._hasResource["dojox.wire.TreeAdapter"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.wire.TreeAdapter"] = true;
+dojo.provide("dojox.wire.TreeAdapter");
+
+dojo.require("dojox.wire.CompositeWire");
+
+dojo.declare("dojox.wire.TreeAdapter", dojox.wire.CompositeWire, {
+ // summary:
+ // A composite Wire for tree nodes
+ // description:
+ // This class has multiple child Wires for tree nodes, their title and
+ // child nodes.
+ // The root object for this class must be an array.
+ // 'node' Wires in 'nodes' property is used to identify an object
+ // representing a node.
+ // 'title' Wires in 'nodes' property is used to get the title string
+ // of a node.
+ // 'children' Wires in 'nodes' property is used to iterate over child
+ // node objects.
+ // The node values are returned in an array as follows:
+ // [
+ // {title: title1,
+ // children: [
+ // {title: title2,
+ // child: ...},
+ // {title: title3,
+ // child: ...},
+ // ...
+ // ]},
+ // ...
+ // ]
+ // This class only supports getValue(), but not setValue().
+
+ _wireClass: "dojox.wire.TreeAdapter",
+
+ constructor: function(/*Object*/args){
+ // summary:
+ // Initialize properties
+ // description:
+ // If object properties ('node', 'title' and 'children') of array
+ // elements specified in 'nodes' property are not Wires, Wires are
+ // created from them as arguments, with 'parent' property set to
+ // this Wire instance.
+ // args:
+ // Arguments to initialize properties
+ // nodes:
+ // An array containing objects for child Wires for node values
+ this._initializeChildren(this.nodes);
+ },
+ _getValue: function(/*Array*/object){
+ // summary:
+ // Return an array of tree node values
+ // description:
+ // This method iterates over an array specified to 'object'
+ // argument and calls getValue() method of 'node' Wires with each
+ // element of the array to get object(s) that represetns nodes.
+ // (If 'node' Wires are omitted, the array element is used for
+ // further processing.)
+ // Then, getValue() method of 'title' Wires are called to get
+ // title strings for nodes.
+ // (If 'title' Wires are omitted, the objects representing nodes
+ // are used as title strings.)
+ // And if an array of objects with 'node' and 'title' Wires is
+ // specified to 'children', it is used to gather child nodes and
+ // their title strings in the same way recursively.
+ // Finally, an array of the top-level node objects are retuned.
+ // object:
+ // A root array
+ // returns:
+ // An array of tree node values
+ if(!object || !this.nodes){
+ return object; //Array
+ }
+
+ var array = object;
+ if(!dojo.isArray(array)){
+ array = [array];
+ }
+
+ var nodes = [];
+ for(var i in array){
+ for(var i2 in this.nodes){
+ nodes = nodes.concat(this._getNodes(array[i], this.nodes[i2]));
+ }
+ }
+ return nodes; //Array
+ },
+
+ _setValue: function(/*Array*/object, /*Array*/value){
+ // summary:
+ // Not supported
+ throw new Error("Unsupported API: " + this._wireClass + "._setValue");
+ },
+
+ _initializeChildren: function(/*Array*/children){
+ // summary:
+ // Initialize child Wires
+ // description:
+ // If 'node' or 'title' properties of array elements specified in
+ // 'children' argument are not Wires, Wires are created from them
+ // as arguments, with 'parent' property set to this Wire instance.
+ // If an array element has 'children' property, this method is
+ // called recursively with it.
+ // children:
+ // An array of objects containing child Wires
+ if(!children){
+ return; //undefined
+ }
+
+ for(var i in children){
+ var child = children[i];
+ if(child.node){
+ child.node.parent = this;
+ if(!dojox.wire.isWire(child.node)){
+ child.node = dojox.wire.create(child.node);
+ }
+ }
+ if(child.title){
+ child.title.parent = this;
+ if(!dojox.wire.isWire(child.title)){
+ child.title = dojox.wire.create(child.title);
+ }
+ }
+ if(child.children){
+ this._initializeChildren(child.children);
+ }
+ }
+ },
+
+ _getNodes: function(/*Object*/object, /*Object*/child){
+ // summary:
+ // Return an array of tree node values
+ // description:
+ // This method calls getValue() method of 'node' Wires with
+ // 'object' argument to get object(s) that represents nodes.
+ // (If 'node' Wires are omitted, 'object' is used for further
+ // processing.)
+ // Then, getValue() method of 'title' Wires are called to get
+ // title strings for nodes.
+ // (If 'title' Wires are omitted, the objects representing nodes
+ // are used as title strings.)
+ // And if an array of objects with 'node' and 'title' Wires is
+ // specified to 'children', it is used to gather child nodes and
+ // their title strings in the same way recursively.
+ // Finally, an array of node objects are returned.
+ // object:
+ // An object
+ // child:
+ // An object with child Wires
+ // returns:
+ var array = null;
+ if(child.node){
+ array = child.node.getValue(object);
+ if(!array){
+ return [];
+ }
+ if(!dojo.isArray(array)){
+ array = [array];
+ }
+ }else{
+ array = [object];
+ }
+
+ var nodes = [];
+ for(var i in array){
+ object = array[i];
+ var node = {};
+ if(child.title){
+ node.title = child.title.getValue(object);
+ }else{
+ node.title = object;
+ }
+ if(child.children){
+ var children = [];
+ for(var i2 in child.children){
+ children = children.concat(this._getNodes(object, child.children[i2]));
+ }
+ if(children.length > 0){
+ node.children = children;
+ }
+ }
+ nodes.push(node);
+ }
+ return nodes; //Array
+ }
+});
+
+}
diff --git a/includes/js/dojox/wire/Wire.js b/includes/js/dojox/wire/Wire.js
new file mode 100644
index 0000000..f9dde1d
--- /dev/null
+++ b/includes/js/dojox/wire/Wire.js
@@ -0,0 +1,336 @@
+if(!dojo._hasResource["dojox.wire.Wire"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.wire.Wire"] = true;
+dojo.provide("dojox.wire.Wire");
+
+dojo.require("dojox.wire._base");
+
+dojo.declare("dojox.wire.Wire", null, {
+ // summary:
+ // A default and base Wire to access an object property
+ // description:
+ // This class accesses a property of an object with a dotted notation
+ // specified to 'property' property, such as "a.b.c", which identifies
+ // a descendant property, "object.a.b.c".
+ // Property names in the dotted notation may have an array index, such
+ // as "a[0]", to identify an array element, literally, "object.a[0]".
+ // When a notation start with an array index, such as "[0].a", it
+ // specifies an array element of the root object (array),
+ // "object[0].a".
+ // This class also serves as a base class for other Wire classes,
+ // preparing a root object and converting a return value, so that
+ // sub-classes just can implement _getValue() and _setValue() called
+ // from getValue() and setValue() implemented by this calss.
+
+ _wireClass: "dojox.wire.Wire",
+
+ constructor: function(/*Object*/args){
+ // summary:
+ // Initialize properties
+ // description:
+ // If 'converter' property is specified and is a string for
+ // a converter class, an instanceof the converter class is
+ // created.
+ // args:
+ // Arguments to initialize properties
+ // object:
+ // A root object (or another Wire to access a root object)
+ // property:
+ // A dotted notation to a descendant property
+ // type:
+ // A type of the return value (for the source Wire)
+ // converter:
+ // A converter object (or class name) to convert the return
+ // value (for the source Wire)
+ dojo.mixin(this, args);
+
+ if(this.converter){
+ if(dojo.isString(this.converter)){
+ //First check the object tree for it. Might be defined variable
+ //name/global function (like a jsId, or just a function name).
+ var convertObject = dojo.getObject(this.converter);
+ if (dojo.isFunction(convertObject)){
+ //We need to see if this is a pure function or an object constructor...
+ try{
+ var testObj = new convertObject();
+ if(testObj && !dojo.isFunction(testObj["convert"])){
+ //Looks like a 'pure' function...
+ this.converter = {convert: convertObject};
+ }else{
+ this.converter = testObj;
+ }
+ }catch(e){
+ //Do if this fails.
+ }
+ }else if(dojo.isObject(convertObject)){
+ //It's an object, like a jsId ... see if it has a convert function
+ if(dojo.isFunction(convertObject["convert"])){
+ this.converter = convertObject;
+ }
+ }
+
+ //No object with that name (Converter is still a string),
+ //then look for a class that needs to be dynamically loaded...
+ if (dojo.isString(this.converter)) {
+ var converterClass = dojox.wire._getClass(this.converter);
+ if(converterClass){
+ this.converter = new converterClass();
+ }else{
+ this.converter = undefined;
+ }
+ }
+ }else if(dojo.isFunction(this.converter)){
+ this.converter = {convert: this.converter};
+ }
+ }
+ },
+
+ getValue: function(/*Object||Array*/defaultObject){
+ // summary:
+ // Return a value of an object
+ // description:
+ // This method first determins a root object as follows:
+ // 1. If 'object' property specified,
+ // 1.1 If 'object' is a Wire, its getValue() method is called to
+ // obtain a root object.
+ // 1.2 Otherwise, use 'object' as a root object.
+ // 2. Otherwise, use 'defaultObject' argument.
+ // 3. If 'property' is specified, it is used to get a property
+ // value.
+ // Then, if a sub-class implements _getValue() method, it is
+ // called with the root object to get the return value.
+ // Otherwise, the root object (typically, a property valye) is
+ // used for the return value.
+ // Finally, if 'type' property is specified, the return value is
+ // converted to the specified primitive type ("string", "number",
+ // "boolean" and "array").
+ // If 'converter' property is specified, its convert() method is
+ // called to convert the value.
+ // defaultObject:
+ // A default root object
+ // returns:
+ // A value found
+ var object = undefined;
+ if(dojox.wire.isWire(this.object)){
+ object = this.object.getValue(defaultObject);
+ }else{
+ object = (this.object || defaultObject);
+ }
+
+ if(this.property){
+ var list = this.property.split('.');
+ for(var i in list){
+ if(!object){
+ return object; //anything (null, undefined, etc)
+ }
+ object = this._getPropertyValue(object, list[i]);
+ }
+ }
+
+ var value = undefined;
+ if(this._getValue){
+ value = this._getValue(object);
+ }else{
+ value = object;
+ }
+
+ if(value){
+ if(this.type){
+ if(this.type == "string"){
+ value = value.toString();
+ }else if(this.type == "number"){
+ value = parseInt(value);
+ }else if(this.type == "boolean"){
+ value = (value != "false");
+ }else if(this.type == "array"){
+ if(!dojo.isArray(value)){
+ value = [value];
+ }
+ }
+ }
+ if(this.converter && this.converter.convert){
+ value = this.converter.convert(value, this); // optional "this" context
+ }
+ }
+ return value; //anything
+ },
+
+ setValue: function(/*anything*/value, /*Object||Array*/defaultObject){
+ // summary:
+ // Set a value to an object
+ // description:
+ // This method first determins a root object as follows:
+ // 1. If 'object' property specified,
+ // 1.1 If 'object' is a Wire, its getValue() method is called to
+ // obtain a root object.
+ // 1.2 Otherwise, use 'object' as a root object.
+ // 2. Otherwise, use 'defaultObject' argument.
+ // 3. If 'property' is specified, it is used to get a property
+ // value.
+ // Then, if a sub-class implements _setValue() method, it is
+ // called with the root object and 'value' argument to set
+ // the value.
+ // Otherwise, 'value' is set to a property specified with
+ // 'property' property.
+ // If the root object is undefined and 'object' property is a Wire
+ // and a new object is created and returned by _setValue() it is
+ // set through 'object' (setValue() method).
+ // value:
+ // A value to set
+ // defaultObject:
+ // A default root object
+ var object = undefined;
+ if(dojox.wire.isWire(this.object)){
+ object = this.object.getValue(defaultObject);
+ }else{
+ object = (this.object || defaultObject);
+ }
+
+ var property = undefined;
+ if(this.property){
+ if(!object){
+ if(dojox.wire.isWire(this.object)){
+ object = {};
+ this.object.setValue(object, defaultObject);
+ }else{
+ throw new Error(this._wireClass + ".setValue(): invalid object");
+ }
+ }
+ var list = this.property.split('.');
+ var last = list.length - 1;
+ for(var i = 0; i < last; i++){
+ var p = list[i];
+ var o = this._getPropertyValue(object, p);
+ if(!o){
+ o = {};
+ this._setPropertyValue(object, p, o);
+ }
+ object = o;
+ }
+ property = list[last];
+ }
+
+ if(this._setValue){
+ if(property){
+ var o = this._getPropertyValue(object, property);
+ if(!o){
+ o = {};
+ this._setPropertyValue(object, property, o);
+ }
+ object = o;
+ }
+ var newObject = this._setValue(object, value);
+ if(!object && newObject){
+ if(dojox.wire.isWire(this.object)){
+ this.object.setValue(newObject, defaultObject);
+ }else{
+ throw new Error(this._wireClass + ".setValue(): invalid object");
+ }
+ }
+ }else{
+ if(property){
+ this._setPropertyValue(object, property, value);
+ }else{
+ if(dojox.wire.isWire(this.object)){
+ this.object.setValue(value, defaultObject);
+ }else{
+ throw new Error(this._wireClass + ".setValue(): invalid property");
+ }
+ }
+ }
+ },
+
+ _getPropertyValue: function(/*Object||Array*/object, /*String*/property){
+ // summary:
+ // Return a property value of an object
+ // description:
+ // A value for 'property' of 'object' is returned.
+ // If 'property' ends with an array index, it is used to indentify
+ // an element of an array property.
+ // If 'object' implements getPropertyValue(), it is called with
+ // 'property' to obtain the property value.
+ // If 'object' implements a getter for the property, it is called
+ // to obtain the property value.
+ // object:
+ // A default root object
+ // property:
+ // A property name
+ // returns:
+ // A value found, otherwise 'undefined'
+ var value = undefined;
+ var i1 = property.indexOf('[');
+ if(i1 >= 0){
+ var i2 = property.indexOf(']');
+ var index = property.substring(i1 + 1, i2);
+ var array = null;
+ if(i1 === 0){ // object is array
+ array = object;
+ }else{
+ property = property.substring(0, i1);
+ array = this._getPropertyValue(object, property);
+ if(array && !dojo.isArray(array)){
+ array = [array];
+ }
+ }
+ if(array){
+ value = array[index];
+ }
+ }else if(object.getPropertyValue){
+ value = object.getPropertyValue(property);
+ }else{
+ var getter = "get" + property.charAt(0).toUpperCase() + property.substring(1);
+ if(object[getter]){
+ value = object[getter]();
+ }else{
+ value = object[property];
+ }
+ }
+ return value; //anything
+ },
+
+ _setPropertyValue: function(/*Object||Array*/object, /*String*/property, /*anything*/value){
+ // summary:
+ // Set a property value to an object
+ // description:
+ // 'value' is set to 'property' of 'object'.
+ // If 'property' ends with an array index, it is used to indentify
+ // an element of an array property to set the value.
+ // If 'object' implements setPropertyValue(), it is called with
+ // 'property' and 'value' to set the property value.
+ // If 'object' implements a setter for the property, it is called
+ // with 'value' to set the property value.
+ // object:
+ // An object
+ // property:
+ // A property name
+ // value:
+ // A value to set
+ var i1 = property.indexOf('[');
+ if(i1 >= 0){
+ var i2 = property.indexOf(']');
+ var index = property.substring(i1 + 1, i2);
+ var array = null;
+ if(i1 === 0){ // object is array
+ array = object;
+ }else{
+ property = property.substring(0, i1);
+ array = this._getPropertyValue(object, property);
+ if(!array){
+ array = [];
+ this._setPropertyValue(object, property, array);
+ }
+ }
+ array[index] = value;
+ }else if(object.setPropertyValue){
+ object.setPropertyValue(property, value);
+ }else{
+ var setter = "set" + property.charAt(0).toUpperCase() + property.substring(1);
+ if(object[setter]){
+ object[setter](value);
+ }else{
+ object[property] = value;
+ }
+ }
+ }
+});
+
+}
diff --git a/includes/js/dojox/wire/XmlWire.js b/includes/js/dojox/wire/XmlWire.js
new file mode 100644
index 0000000..dc5666f
--- /dev/null
+++ b/includes/js/dojox/wire/XmlWire.js
@@ -0,0 +1,244 @@
+if(!dojo._hasResource["dojox.wire.XmlWire"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.wire.XmlWire"] = true;
+dojo.provide("dojox.wire.XmlWire");
+
+dojo.require("dojox.data.dom");
+dojo.require("dojox.wire.Wire");
+
+dojo.declare("dojox.wire.XmlWire", dojox.wire.Wire, {
+ // summary:
+ // A Wire for XML nodes or values (element, attribute and text)
+ // description:
+ // This class accesses XML nodes or value with a simplified XPath
+ // specified to 'path' property.
+ // The root object for this class must be an DOM document or element
+ // node.
+ // "@name" accesses to an attribute value of an element and "text()"
+ // accesses to a text value of an element.
+ // The hierarchy of the elements from the root node can be specified
+ // with slash-separated list, such as "a/b/@c", which specifies
+ // the value of an attribute named "c" of an element named "b" as
+ // a child of another element named "a" of a child of the root node.
+
+ _wireClass: "dojox.wire.XmlWire",
+
+ constructor: function(/*Object*/args){
+ // summary:
+ // Initialize properties
+ // description:
+ // 'args' is just mixed in with no further processing.
+ // args:
+ // Arguments to initialize properties
+ // path:
+ // A simplified XPath to an attribute, a text or elements
+ },
+ _getValue: function(/*Node*/object){
+ // summary:
+ // Return an attribute value, a text value or an array of elements
+ // description:
+ // This method first uses a root node passed in 'object' argument
+ // and 'path' property to identify an attribute, a text or
+ // elements.
+ // If 'path' starts with a slash (absolute), the first path
+ // segment is ignored assuming it point to the root node.
+ // (That is, "/a/b/@c" and "b/@c" against a root node access
+ // the same attribute value, assuming the root node is an element
+ // with a tag name, "a".)
+ // object:
+ // A root node
+ // returns:
+ // A value found, otherwise 'undefined'
+ if(!object || !this.path){
+ return object; //Node
+ }
+
+ var node = object;
+ var path = this.path;
+ if(path.charAt(0) == '/'){ // absolute
+ // skip the first expression (supposed to select the top node)
+ var i = path.indexOf('/', 1);
+ path = path.substring(i + 1);
+ }
+ var list = path.split('/');
+ var last = list.length - 1;
+ for(var i = 0; i < last; i++){
+ node = this._getChildNode(node, list[i]);
+ if(!node){
+ return undefined; //undefined
+ }
+ }
+ var value = this._getNodeValue(node, list[last]);
+ return value; //String||Array
+ },
+
+ _setValue: function(/*Node*/object, /*String*/value){
+ // summary:
+ // Set an attribute value or a child text value to an element
+ // description:
+ // This method first uses a root node passed in 'object' argument
+ // and 'path' property to identify an attribute, a text or
+ // elements.
+ // If an intermediate element does not exist, it creates
+ // an element of the tag name in the 'path' segment as a child
+ // node of the current node.
+ // Finally, 'value' argument is set to an attribute or a text
+ // (a child node) of the leaf element.
+ // object:
+ // A root node
+ // value:
+ // A value to set
+ if(!this.path){
+ return object; //Node
+ }
+
+ var node = object;
+ var doc = this._getDocument(node);
+ var path = this.path;
+ if(path.charAt(0) == '/'){ // absolute
+ var i = path.indexOf('/', 1);
+ if(!node){
+ var name = path.substring(1, i);
+ node = doc.createElement(name);
+ object = node; // to be returned as a new object
+ }
+ // skip the first expression (supposed to select the top node)
+ path = path.substring(i + 1);
+ }else{
+ if(!node){
+ return undefined; //undefined
+ }
+ }
+
+ var list = path.split('/');
+ var last = list.length - 1;
+ for(var i = 0; i < last; i++){
+ var child = this._getChildNode(node, list[i]);
+ if(!child){
+ child = doc.createElement(list[i]);
+ node.appendChild(child);
+ }
+ node = child;
+ }
+ this._setNodeValue(node, list[last], value);
+ return object; //Node
+ },
+
+ _getNodeValue: function(/*Node*/node, /*String*/exp){
+ // summary:
+ // Return an attribute value, a text value or an array of elements
+ // description:
+ // If 'exp' starts with '@', an attribute value of the specified
+ // attribute is returned.
+ // If 'exp' is "text()", a child text value is returned.
+ // Otherwise, an array of child elements, the tag name of which
+ // match 'exp', is returned.
+ // node:
+ // A node
+ // exp:
+ // An expression for attribute, text or elements
+ // returns:
+ // A value found, otherwise 'undefined'
+ var value = undefined;
+ if(exp.charAt(0) == '@'){
+ var attribute = exp.substring(1);
+ value = node.getAttribute(attribute);
+ }else if(exp == "text()"){
+ var text = node.firstChild;
+ if(text){
+ value = text.nodeValue;
+ }
+ }else{ // assume elements
+ value = [];
+ for(var i = 0; i < node.childNodes.length; i++){
+ var child = node.childNodes[i];
+ if(child.nodeType === 1 /* ELEMENT_NODE */ && child.nodeName == exp){
+ value.push(child);
+ }
+ }
+ }
+ return value; //String||Array
+ },
+
+ _setNodeValue: function(/*Node*/node, /*String*/exp, /*String*/value){
+ // summary:
+ // Set an attribute value or a child text value to an element
+ // description:
+ // If 'exp' starts with '@', 'value' is set to the specified
+ // attribute.
+ // If 'exp' is "text()", 'value' is set to a child text.
+ // node:
+ // A node
+ // exp:
+ // An expression for attribute or text
+ // value:
+ // A value to set
+ if(exp.charAt(0) == '@'){
+ var attribute = exp.substring(1);
+ if(value){
+ node.setAttribute(attribute, value);
+ }else{
+ node.removeAttribute(attribute);
+ }
+ }else if(exp == "text()"){
+ while(node.firstChild){
+ node.removeChild(node.firstChild);
+ }
+ if(value){
+ var text = this._getDocument(node).createTextNode(value);
+ node.appendChild(text);
+ }
+ }
+ // else not supported
+ },
+
+ _getChildNode: function(/*Node*/node, /*String*/name){
+ // summary:
+ // Return a child node
+ // description:
+ // A child element of the tag name specified with 'name' is
+ // returned.
+ // If 'name' ends with an array index, it is used to pick up
+ // the corresponding element from multiple child elements.
+ // node:
+ // A parent node
+ // name:
+ // A tag name
+ // returns:
+ // A child node
+ var index = 1;
+ var i1 = name.indexOf('[');
+ if(i1 >= 0){
+ var i2 = name.indexOf(']');
+ index = name.substring(i1 + 1, i2);
+ name = name.substring(0, i1);
+ }
+ var count = 1;
+ for(var i = 0; i < node.childNodes.length; i++){
+ var child = node.childNodes[i];
+ if(child.nodeType === 1 /* ELEMENT_NODE */ && child.nodeName == name){
+ if(count == index){
+ return child; //Node
+ }
+ count++;
+ }
+ }
+ return null; //null
+ },
+
+ _getDocument: function(/*Node*/node){
+ // summary:
+ // Return a DOM document
+ // description:
+ // If 'node' is specified, a DOM document of the node is returned.
+ // Otherwise, a DOM document is created.
+ // returns:
+ // A DOM document
+ if(node){
+ return (node.nodeType == 9 /* DOCUMENT_NODE */ ? node : node.ownerDocument); //Document
+ }else{
+ return dojox.data.dom.createDocument(); //Document
+ }
+ }
+});
+
+}
diff --git a/includes/js/dojox/wire/_base.js b/includes/js/dojox/wire/_base.js
new file mode 100644
index 0000000..cc632c1
--- /dev/null
+++ b/includes/js/dojox/wire/_base.js
@@ -0,0 +1,195 @@
+if(!dojo._hasResource["dojox.wire._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.wire._base"] = true;
+dojo.provide("dojox.wire._base");
+
+dojox.wire._defaultWireClass = "dojox.wire.Wire";
+
+dojox.wire._wireClasses = {
+ "attribute": "dojox.wire.DataWire",
+ "path": "dojox.wire.XmlWire",
+ "children": "dojox.wire.CompositeWire",
+ "columns": "dojox.wire.TableAdapter",
+ "nodes": "dojox.wire.TreeAdapter",
+ "segments": "dojox.wire.TextAdapter"
+};
+
+dojox.wire.register = function(/*Function||String*/wireClass, /*String*/key){
+ // summary:
+ // Register a Wire class
+ // desription:
+ // The specified Wire class or a class name is registered with
+ // a key property of arguments to create a Wire
+ // wireClass:
+ // A class or full qualified class name
+ // key:
+ // A key property of arguments to create a Wire
+ if(!wireClass || !key){
+ return; //undefined
+ }
+ if(dojox.wire._wireClasses[key]){ // key already in use
+ return; //undefined
+ }
+ dojox.wire._wireClasses[key] = wireClass;
+};
+
+dojox.wire._getClass = function(/*String*/name){
+ // summary:
+ // Returns a class
+ // description:
+ // The class is loaded by dojo.require() and returned
+ // by dojo.getObject().
+ // name:
+ // A class name
+ // returns:
+ // A class
+ dojo["require"](name); // use dojo["require"] instead of dojo.require to avoid a build problem
+ return dojo.getObject(name); //Function
+};
+
+dojox.wire.create = function(/*Object*/args){
+ // summary:
+ // Create a Wire from arguments
+ // description:
+ // If 'args' specifies 'wireClass', it is used as a class or full
+ // qualified class name to create a Wire with 'args' as arguments.
+ // Otherwise, a Wire class is determined by other proeprties of 'args'
+ // checking if 'args' specifies a key property for a Wire class.
+ // If no key property found, the default Wire class is used.
+ // args:
+ // Arguments to create a Wire
+ // returns:
+ // A Wire
+ if(!args){
+ args = {};
+ }
+ var wireClass = args.wireClass;
+ if(wireClass){
+ if(dojo.isString(wireClass)){
+ wireClass = dojox.wire._getClass(wireClass);
+ }
+ }else{
+ for(var key in args){
+ if(!args[key]){
+ continue;
+ }
+ wireClass = dojox.wire._wireClasses[key];
+ if(wireClass){
+ if(dojo.isString(wireClass)){
+ wireClass = dojox.wire._getClass(wireClass);
+ dojox.wire._wireClasses[key] = wireClass;
+ }
+ break;
+ }
+ }
+ }
+ if(!wireClass){
+ if(dojo.isString(dojox.wire._defaultWireClass)){
+ dojox.wire._defaultWireClass = dojox.wire._getClass(dojox.wire._defaultWireClass);
+ }
+ wireClass = dojox.wire._defaultWireClass;
+ }
+ return new wireClass(args); //Object
+};
+
+dojox.wire.isWire = function(/*Object*/wire){
+ // summary:
+ // Check if an object is a Wire
+ // description:
+ // If the specified object is a Wire, true is returned.
+ // Otherwise, false is returned.
+ // wire:
+ // An object to check
+ // returns:
+ // True if the object is a Wire, otherwise false
+ return (wire && wire._wireClass); //Boolean
+};
+
+dojox.wire.transfer = function(/*Wire||Object*/source, /*Wire||Object*/target, /*Object?*/defaultObject, /*Object?*/defaultTargetObject){
+ // summary:
+ // Transfer a source value to a target value
+ // description:
+ // If 'source' and/or 'target' are not Wires, Wires are created with
+ // them as arguments.
+ // A value is got through the source Wire and set through the target
+ // Wire.
+ // 'defaultObject' is passed to Wires as a default root object.
+ // If 'defaultTargetObject' is specified, it is passed to the target
+ // Wire as a default root object, instead of 'defaultObject'.
+ // source:
+ // A Wire or arguments to create a Wire for a source value
+ // target:
+ // A Wire or arguments to create a Wire for a target value
+ // defaultObject:
+ // defaultTargetObject;
+ // Optional default root objects passed to Wires
+ if(!source || !target){
+ return; //undefined
+ }
+ if(!dojox.wire.isWire(source)){
+ source = dojox.wire.create(source);
+ }
+ if(!dojox.wire.isWire(target)){
+ target = dojox.wire.create(target);
+ }
+
+ var value = source.getValue(defaultObject);
+ target.setValue(value, (defaultTargetObject || defaultObject));
+};
+
+dojox.wire.connect = function(/*Object*/trigger, /*Wire||Object*/source, /*Wire||Object*/target){
+ // summary:
+ // Transfer a source value to a target value on a trigger event or
+ // topic
+ // description:
+ // If 'trigger' specifies 'topic', the topic is subscribed to transer
+ // a value on the topic.
+ // Otherwise, the event specified to 'event' of 'trigger' is listened
+ // to transfer a value.
+ // On the specified event or topic, transfer() is called with
+ // 'source', 'target' and the arguments of the event or topic (as
+ // default root objects).
+ // trigger:
+ // An event or topic to trigger a transfer
+ // source:
+ // A Wire or arguments to create a Wire for a source value
+ // target:
+ // A Wire or arguments to create a Wire for a target value
+ // returns:
+ // A connection handle for disconnect()
+ if(!trigger || !source || !target){
+ return; //undefined
+ }
+
+ var connection = {topic: trigger.topic};
+ if(trigger.topic){
+ connection.handle = dojo.subscribe(trigger.topic, function(){
+ dojox.wire.transfer(source, target, arguments);
+ });
+ }else if(trigger.event){
+ connection.handle = dojo.connect(trigger.scope, trigger.event, function(){
+ dojox.wire.transfer(source, target, arguments);
+ });
+ }
+ return connection; //Object
+};
+
+dojox.wire.disconnect = function(/*Object*/connection){
+ // summary:
+ // Remove a connection or subscription for transfer
+ // description:
+ // If 'handle' has 'topic', the topic is unsubscribed.
+ // Otherwise, the listener to an event is removed.
+ // connection:
+ // A connection handle returned by connect()
+ if(!connection || !connection.handle){
+ return; //undefined
+ }
+
+ if(connection.topic){
+ dojo.unsubscribe(connection.handle);
+ }else{
+ dojo.disconnect(connection.handle);
+ }
+};
+
+}
diff --git a/includes/js/dojox/wire/demos/TableContainer.css b/includes/js/dojox/wire/demos/TableContainer.css
new file mode 100644
index 0000000..fded51f
--- /dev/null
+++ b/includes/js/dojox/wire/demos/TableContainer.css
@@ -0,0 +1,25 @@
+.tablecontainer {
+ padding: 3 3 3 3;
+ border-width: 1px;
+ border-style: solid;
+ border-color: #000000;
+ border-collapse: separate;
+}
+.tablecontainer th {
+ text-align: left;
+}
+.tablecontainer tr {
+ padding: 3 3 3 3;
+ border-width: 1px;
+ border-style: solid;
+ border-color: #000000;
+}
+.tablecontainer tr td {
+ padding: 3 3 3 3;
+ border-width: 1px;
+ border-style: solid;
+ border-color: #000000;
+}
+.alternate {
+ background-color: #EEEEEE;
+}
diff --git a/includes/js/dojox/wire/demos/TableContainer.css.commented.css b/includes/js/dojox/wire/demos/TableContainer.css.commented.css
new file mode 100644
index 0000000..4ee2706
--- /dev/null
+++ b/includes/js/dojox/wire/demos/TableContainer.css.commented.css
@@ -0,0 +1,30 @@
+.tablecontainer {
+ padding: 3 3 3 3;
+ border-width: 1px;
+ border-style: solid;
+ border-color: #000000;
+ border-collapse: separate;
+}
+
+.tablecontainer th {
+ text-align: left;
+}
+
+.tablecontainer tr {
+ padding: 3 3 3 3;
+ border-width: 1px;
+ border-style: solid;
+ border-color: #000000;
+}
+
+.tablecontainer tr td {
+ padding: 3 3 3 3;
+ border-width: 1px;
+ border-style: solid;
+ border-color: #000000;
+}
+
+.alternate {
+ background-color: #EEEEEE;
+}
+
diff --git a/includes/js/dojox/wire/demos/TableContainer.js b/includes/js/dojox/wire/demos/TableContainer.js
new file mode 100644
index 0000000..fd4ad73
--- /dev/null
+++ b/includes/js/dojox/wire/demos/TableContainer.js
@@ -0,0 +1,68 @@
+if(!dojo._hasResource["dojox.wire.demos.TableContainer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.wire.demos.TableContainer"] = true;
+dojo.provide("dojox.wire.demos.TableContainer");
+
+dojo.require("dojo.parser");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+
+dojo.declare("dojox.wire.demos.TableContainer", [ dijit._Widget, dijit._Templated, dijit._Container ], {
+ // summary:
+ // Extremely simple 'widget' that is a table generator with an addRow function that takes an array
+ // as the row to add, where each entry is a cell in the row. This demo widget is for use with the
+ // wire demos.
+
+ templateString: "<table class='tablecontainer'><tbody dojoAttachPoint='tableContainer'></tbody></table>",
+ rowCount: 0,
+ headers: "",
+ addRow: function(array){
+ // summary:
+ // Function to add in a new row from the elements in the array map to cells in the row.
+ // array:
+ // Array of row values to add.
+ try{
+ var row = document.createElement("tr");
+ if((this.rowCount%2) === 0){
+ dojo.addClass(row, "alternate");
+ }
+ this.rowCount++;
+ for(var i in array){
+ var cell = document.createElement("td");
+ var text = document.createTextNode(array[i]);
+ cell.appendChild(text);
+ row.appendChild(cell);
+
+ }
+ this.tableContainer.appendChild(row);
+ }catch(e){ console.debug(e); }
+ },
+
+ clearTable: function(){
+ // summary:
+ // Function to clear all the current rows in the table, except for the header.
+
+ //Always leave the first row, which is the table header.
+ while(this.tableContainer.firstChild.nextSibling){
+ this.tableContainer.removeChild(this.tableContainer.firstChild.nextSibling);
+ }
+ this.rowCount = 0;
+ },
+
+ postCreate: function(){
+ // summary:
+ // Widget lifecycle function to handle generation of the header elements in the table.
+ var headers = this.headers.split(",");
+ var tr = document.createElement("tr");
+ for(i in headers){
+
+ var header = headers[i];
+ var th = document.createElement("th");
+ var text = document.createTextNode(header);
+ th.appendChild(text);
+ tr.appendChild(th);
+ }
+ this.tableContainer.appendChild(tr);
+ }
+});
+
+}
diff --git a/includes/js/dojox/wire/demos/WidgetRepeater.js b/includes/js/dojox/wire/demos/WidgetRepeater.js
new file mode 100644
index 0000000..ad1b8b0
--- /dev/null
+++ b/includes/js/dojox/wire/demos/WidgetRepeater.js
@@ -0,0 +1,33 @@
+if(!dojo._hasResource["dojox.wire.demos.WidgetRepeater"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.wire.demos.WidgetRepeater"] = true;
+dojo.provide("dojox.wire.demos.WidgetRepeater")
+
+dojo.require("dojo.parser");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dijit._Container");
+
+dojo.declare("dojox.wire.demos.WidgetRepeater", [ dijit._Widget, dijit._Templated, dijit._Container ], {
+ // summary:
+ // Simple widget that does generation of widgets repetatively, based on calls to
+ // the createNew function and contains them as child widgets.
+ templateString: "<div class='WidgetRepeater' dojoAttachPoint='repeaterNode'></div>",
+ widget: null,
+ repeater: null,
+ createNew: function(obj){
+ // summary:
+ // Function to handle the creation of a new widget and appending it into the widget tree.
+ // obj:
+ // The parameters to pass to the widget.
+ try{
+ if(dojo.isString(this.widget)){
+ dojo.require(this.widget);
+ this.widget = dojo.getObject(this.widget);
+ }
+ this.addChild(new this.widget(obj));
+ this.repeaterNode.appendChild(document.createElement("br"));
+ }catch(e){ console.debug(e); }
+ }
+});
+
+}
diff --git a/includes/js/dojox/wire/demos/markup/countries.json b/includes/js/dojox/wire/demos/markup/countries.json
new file mode 100644
index 0000000..ad3a07a
--- /dev/null
+++ b/includes/js/dojox/wire/demos/markup/countries.json
@@ -0,0 +1,43 @@
+{ identifier: 'name',
+ items: [
+ { name:'Africa', type:'continent',
+ children:[{_reference:'Egypt'}, {_reference:'Kenya'}, {_reference:'Sudan'}] },
+ { name:'Egypt', type:'country' },
+ { name:'Kenya', type:'country',
+ children:[{_reference:'Nairobi'}, {_reference:'Mombasa'}] },
+ { name:'Nairobi', type:'city' },
+ { name:'Mombasa', type:'city' },
+ { name:'Sudan', type:'country',
+ children:{_reference:'Khartoum'} },
+ { name:'Khartoum', type:'city' },
+ { name:'Asia', type:'continent',
+ children:[{_reference:'China'}, {_reference:'India'}, {_reference:'Russia'}, {_reference:'Mongolia'}] },
+ { name:'China', type:'country' },
+ { name:'India', type:'country' },
+ { name:'Russia', type:'country' },
+ { name:'Mongolia', type:'country' },
+ { name:'Australia', type:'continent', population:'21 million',
+ children:{_reference:'Commonwealth of Australia'}},
+ { name:'Commonwealth of Australia', type:'country', population:'21 million'},
+ { name:'Europe', type:'continent',
+ children:[{_reference:'Germany'}, {_reference:'France'}, {_reference:'Spain'}, {_reference:'Italy'}] },
+ { name:'Germany', type:'country' },
+ { name:'France', type:'country' },
+ { name:'Spain', type:'country' },
+ { name:'Italy', type:'country' },
+ { name:'North America', type:'continent',
+ children:[{_reference:'Mexico'}, {_reference:'Canada'}, {_reference:'United States of America'}] },
+ { name:'Mexico', type:'country', population:'108 million', area:'1,972,550 sq km',
+ children:[{_reference:'Mexico City'}, {_reference:'Guadalajara'}] },
+ { name:'Mexico City', type:'city', population:'19 million', timezone:'-6 UTC'},
+ { name:'Guadalajara', type:'city', population:'4 million', timezone:'-6 UTC' },
+ { name:'Canada', type:'country', population:'33 million', area:'9,984,670 sq km',
+ children:[{_reference:'Ottawa'}, {_reference:'Toronto'}] },
+ { name:'Ottawa', type:'city', population:'0.9 million', timezone:'-5 UTC'},
+ { name:'Toronto', type:'city', population:'2.5 million', timezone:'-5 UTC' },
+ { name:'United States of America', type:'country' },
+ { name:'South America', type:'continent',
+ children:[{_reference:'Brazil'}, {_reference:'Argentina'}] },
+ { name:'Brazil', type:'country', population:'186 million' },
+ { name:'Argentina', type:'country', population:'40 million' }
+]}
diff --git a/includes/js/dojox/wire/demos/markup/demo_ActionChaining.html b/includes/js/dojox/wire/demos/markup/demo_ActionChaining.html
new file mode 100644
index 0000000..596d6ec
--- /dev/null
+++ b/includes/js/dojox/wire/demos/markup/demo_ActionChaining.html
@@ -0,0 +1,108 @@
+<!--
+ This file demonstrates how the dojox.wire code can be used to do declarative
+ wiring of events. Specifically, it shows how you can chain actions together
+ in a sequence. In this case the setting of a value on one textbox triggers a
+ copy over to another textbox. That in turn triggers yet another copy to another
+ text box.
+-->
+<html>
+<head>
+ <title>Sample Action Chaining</title>
+ <style type="text/css">
+
+ @import "../../../../dijit/themes/tundra/tundra.css";
+ @import "../../../../dojo/resources/dojo.css";
+ @import "../../../../dijit/tests/css/dijitTests.css";
+ @import "../TableContainer.css";
+
+ .splitView {
+ width: 90%;
+ height: 90%;
+ border: 1px solid #bfbfbf;
+ border-collapse: separate;
+ }
+ </style>
+
+ <script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+ <script type="text/javascript">
+ dojo.require("dojo.parser");
+ dojo.require("dojox.wire");
+ dojo.require("dojox.wire.ml.Invocation");
+ dojo.require("dojox.wire.ml.DataStore");
+ dojo.require("dojox.wire.ml.Transfer");
+ dojo.require("dojox.wire.ml.Data");
+ dojo.require("dijit.form.TextBox");
+ </script>
+</head>
+
+<body class="tundra">
+
+ <!-- Layout -->
+ <font size="3"><b>Demo of Chaining Actions:</b></font><br/><br/>
+ This demo shows how you can chain actions together to fire in a sequence.
+ Such as the completion of setting one value on a widget triggers the setting of another value on the widget
+ <br/>
+ <br/>
+ <table>
+ <tr>
+ <td>
+ <div dojoType="dijit.form.TextBox" id="inputField" value="" size="50"></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <div dojoType="dijit.form.TextBox" id="targetField1" value="" disabled="true" size="50"></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <div dojoType="dijit.form.TextBox" id="targetField2" value="" disabled="true" size="50"></div>
+ </td>
+ </tr>
+ </table>
+
+
+ <!-------------------------------- Using dojox.wire, declaratively wire up the widgets. --------------------------->
+
+ <!--
+ This is an example of using the declarative data value definition.
+ These are effectively declarative variables to act as placeholders
+ for data values.
+ -->
+ <div dojoType="dojox.wire.ml.Data"
+ id="data">
+ <div dojoType="dojox.wire.ml.DataProperty"
+ name="tempData"
+ value="">
+ </div>
+ </div>
+
+ <!--
+ Whenever a key is entered into the textbox, copy the value somewhere, then invoke a method on another widget, in this case
+ on just another text box.
+ -->
+ <div dojoType="dojox.wire.ml.Action"
+ id="action1"
+ trigger="inputField"
+ triggerEvent="onkeyup">
+ <div dojoType="dojox.wire.ml.Invocation" object="inputField" method="getValue" result="data.tempData"></div>
+ <div dojoType="dojox.wire.ml.Invocation" id="targetCopy" object="targetField1" method="setValue" parameters="data.tempData"></div>
+ </div>
+
+ <!--
+ Whenever the primary cloning invocation completes, invoke a secondary cloning action.
+ -->
+ <div dojoType="dojox.wire.ml.Action"
+ id="action2"
+ trigger="targetCopy"
+ triggerEvent="onComplete">
+ <!--
+ Note that this uses the basic 'property' form of copying the property over and setting it. The Wire
+ code supports both getX and setX functions of setting a property as well as direct access. It first looks
+ for the getX/setX functions and if present, uses them. If missing, it will just do direct access. Because
+ of the standard getValue/setValue API of dijit form widgets, these transfers work really well and are very compact.
+ -->
+ <div dojoType="dojox.wire.ml.Transfer" source="targetField1.value" target="targetField2.value"></div>
+ </div>
+</body>
+</html>
diff --git a/includes/js/dojox/wire/demos/markup/demo_ActionWiring.html b/includes/js/dojox/wire/demos/markup/demo_ActionWiring.html
new file mode 100644
index 0000000..995b67f
--- /dev/null
+++ b/includes/js/dojox/wire/demos/markup/demo_ActionWiring.html
@@ -0,0 +1,142 @@
+<!--
+ This file demonstrates how the dojox.wire code can be used to do declarative
+ wiring of events on one item to trigger event on other widgets. It also shows
+ how you can use the Transfer object to morph data values from one format to
+ another. In this specific case, it maps the values from a dojo.data Datastore
+ item into values stored in a JavaScript Array, which is the format required for
+ the addRow method of the demonstration TableContainer.
+
+ Note that this demo expects dojo, digit, and dojox to all be peers in the same directory
+ in order for it to execute.
+-->
+<html>
+<head>
+ <title>Sample declarative data binding</title>
+ <style type="text/css">
+
+ @import "../../../../dijit/themes/tundra/tundra.css";
+ @import "../../../../dojo/resources/dojo.css";
+ @import "../../../../dijit/tests/css/dijitTests.css";
+ @import "../TableContainer.css";
+
+ .splitView {
+ width: 90%;
+ height: 90%;
+ border: 1px solid #bfbfbf;
+ border-collapse: separate;
+ }
+ </style>
+
+ <script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+ <script type="text/javascript">
+ dojo.require("dojo.parser");
+ dojo.require("dojox.wire.ml.Invocation");
+ dojo.require("dojox.wire.ml.DataStore");
+ dojo.require("dojox.wire.ml.Transfer");
+
+ dojo.require("dijit.layout.SplitContainer");
+ dojo.require("dijit.layout.LayoutContainer");
+ dojo.require("dijit.layout.ContentPane");
+ dojo.require("dijit.form.Button");
+ dojo.require("dijit.form.TextBox");
+
+ dojo.require("dojo.data.ItemFileReadStore");
+ dojo.require("dojox.wire");
+ dojo.require("dojox.wire.demos.TableContainer");
+
+ //Toplevel JS Object to contain a few basics for us, such as the request to pass to the store and a stub onItem function
+ // to trap on for triggering other events.
+ dataHolder = {
+ //Simple object definition to get all items and sort it by the attribute 'type'.
+ request: {query: {name: "*"}, onItem: function(item, req){}, sort: [{attribute: "type"}]},
+ //Spot to store off data values as they're generated by the declarative binding.
+ result: null
+ };
+
+ </script>
+</head>
+
+<body class="tundra">
+
+ <!-- The following is the basic layout. A split container with a button and a text field. Data will be displayed on the right. -->
+ <div dojoType="dijit.layout.SplitContainer"
+ orientation="horizontal"
+ sizerWidth="7"
+ activeSizing="true"
+ class="splitView">
+ <div dojoType="dijit.layout.ContentPane" sizeMin="50" sizeShare="50">
+ <font size="3"><b>Demo Searcher (Searches on Attribute 'name'):</b></font><br/><br/>
+ <b>Usage:</b><br/>
+ Enter the name you want to search the store for. Wildcards * (multiple character), and ? (single character), are allowed.
+ <br/>
+ <br/>
+ <table style="width: 90%;">
+ <tr>
+ <td align="left">
+ <div dojoType="dijit.form.Button" jsId="searchButton">Search Datastore</div>
+ </td>
+ <td align="right">
+ <div dojoType="dijit.form.TextBox" jsId="inputField" value="*"></div>
+ </td>
+ </tr>
+ </table>
+ </div>
+ <div dojoType="dijit.layout.ContentPane" sizeMin="50" sizeShare="50">
+ <div class="dataTable" dojoType="dojox.wire.demos.TableContainer" jsId="dataTable" headers="Name,Location Type"></div>
+ </div>
+ </div>
+
+
+ <!-------------------------------- Using dojox.wire, declaratively wire up the widgets. --------------------------->
+
+ <!-- The store that is queried in this demo -->
+ <div dojoType="dojo.data.ItemFileReadStore"
+ jsId="DataStore1"
+ url="countries.json">
+ </div>
+
+ <!--
+ When the search button is clicked, clear existing rows from table,
+ Then invoke the fetch to repopulate the table.
+ -->
+ <div dojoType="dojox.wire.ml.Action"
+ trigger="searchButton"
+ triggerEvent="onClick">
+ <div dojoType="dojox.wire.ml.Invocation" object="dataTable" method="clearTable"></div>
+ <div dojoType="dojox.wire.ml.Invocation" object="DataStore1" method="fetch" parameters="dataHolder.request"></div>
+ </div>
+
+ <!--
+ Link existing of the text box to transfering the search string to the query param.
+ We are wiring the value of TextBox value of the widget to the name property of our request
+ object. The copy of values to the search should occur on each keyup event (each keypress)
+ -->
+ <div dojoType="dojox.wire.ml.Transfer"
+ trigger="inputField" triggerEvent="onkeyup"
+ source="inputField.textbox.value"
+ target="dataHolder.request.query.name">
+ </div>
+
+ <!--
+ On the call of the onItem function of 'dataHolder', trigger a binding/mapping of the
+ item's attribute 'name' and 'type' attributes to specific columns in an array. Note here that since
+ sourceStore is set, it treats the arguments as items from that store and accesses the attributes
+ appropriately. In this case 'name' becomes array entry 0, type, array entry 1, and so on.
+
+ Then take the result of the data mapping and pass it into the invoke of the addRow function on the
+ TableContainer widget.
+ -->
+ <div dojoType="dojox.wire.ml.Action"
+ trigger="dataHolder.request" triggerEvent="onItem">
+ <div dojoType="dojox.wire.ml.Transfer"
+ source="arguments[0]" sourceStore="DataStore1"
+ target="dataHolder.result">
+ <div dojoType="dojox.wire.ml.ColumnWire" attribute="name"></div>
+ <div dojoType="dojox.wire.ml.ColumnWire" attribute="type"></div>
+ </div>
+ <div dojoType="dojox.wire.ml.Invocation"
+ object="dataTable" method="addRow" parameters='dataHolder.result'>
+ </div>
+ </div>
+</body>
+</html>
diff --git a/includes/js/dojox/wire/demos/markup/demo_BasicChildWire.html b/includes/js/dojox/wire/demos/markup/demo_BasicChildWire.html
new file mode 100644
index 0000000..f5973e7
--- /dev/null
+++ b/includes/js/dojox/wire/demos/markup/demo_BasicChildWire.html
@@ -0,0 +1,78 @@
+<!--
+ This file demonstrates how the dojox.wire code can be used to do declarative
+ wiring of properties/attributes of some object to the properties/attributes of
+ another object. It specifically uses the Child (Composite) wire type to perform
+ the mapping.
+
+ Note that this demo expects dojo, digit, and dojox to all be peers in the same directory
+ in order for it to execute.
+-->
+<html>
+ <head>
+ <title>Sample Composite (Child) Wire usage.</title>
+ <style type="text/css">
+ @import "../../../../dijit/themes/tundra/tundra.css";
+ @import "../../../../dojo/resources/dojo.css";
+ @import "../../../../dijit/tests/css/dijitTests.css";
+ </style>
+
+ <script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+ <script type="text/javascript">
+ dojo.require("dojo.parser");
+ dojo.require("dijit.form.Button");
+ dojo.require("dojo.data.ItemFileReadStore");
+ dojo.require("dojox.wire.ml.Invocation");
+ dojo.require("dojox.wire.ml.DataStore");
+ dojo.require("dojox.wire.ml.Transfer");
+ dojo.require("dojox.wire");
+ dojo.require("dojox.wire.demos.WidgetRepeater");
+
+ dataHolder = {
+ request: {onItem: function(item){}},
+ result: null
+ };
+ </script>
+ </head>
+ <body class="tundra">
+ <!--
+ On load of the page, invoke the fetch method of the object 'DataStore1',
+ get its parameters from the JS object 'sample.request
+ -->
+ <div dojoType="dojox.wire.ml.Invocation"
+ triggerEvent="onLoad"
+ object="DataStore1" method="fetch" parameters="dataHolder.request">
+ </div>
+
+ <!--
+ The store that is queried in this demo
+ -->
+ <div dojoType="dojo.data.ItemFileReadStore"
+ jsId="DataStore1"
+ url="countries.json">
+ </div>
+
+ <!--
+ Simple container widget for creating a 'list' of some set of widgets
+ As defined by the widget type it contains.
+ -->
+ <div dojoType="dojox.wire.demos.WidgetRepeater"
+ widget="dijit.form.Button" jsId="r1">
+ </div>
+
+ <!--
+ On the call of the onItem function of 'sample', trigger a binding/mapping of the
+ item's attribute 'name' to the target object property: dataHolder.result.caption
+ Then invoke the WidgetRepeater (r1)'s createNew method, using the parameters from
+ dataHolder.result.
+ -->
+ <div dojoType="dojox.wire.ml.Action"
+ trigger="dataHolder.request" triggerEvent="onItem">
+ <div dojoType="dojox.wire.ml.Transfer"
+ source="arguments[0]" sourceStore="DataStore1"
+ target="dataHolder.result">
+ <div dojoType="dojox.wire.ml.ChildWire" name="label" attribute="name"></div>
+ </div>
+ <div dojoType="dojox.wire.ml.Invocation" object="r1" method="createNew" parameters='dataHolder.result'></div>
+ </div>
+ </body>
+</html>
diff --git a/includes/js/dojox/wire/demos/markup/demo_BasicColumnWiring.html b/includes/js/dojox/wire/demos/markup/demo_BasicColumnWiring.html
new file mode 100644
index 0000000..48c327e
--- /dev/null
+++ b/includes/js/dojox/wire/demos/markup/demo_BasicColumnWiring.html
@@ -0,0 +1,90 @@
+<!--
+ This file demonstrates how the dojox.wire code can be used to do declarative
+ wiring of events on one item to trigger event on other items. It also shows
+ how you can use the Transfer object to morph data values from one format to
+ another. In this specific case, it maps the values from a dojo.data Datastore
+ item into values stored in a JavaScript Array, which is the format required for
+ the addRow method of the demonstration TableContainer.
+
+ Note that this demo expects dojo, digit, and dojox to all be peers in the same directory
+ in order for it to execute.
+-->
+<html>
+<head>
+ <title>Sample Declarative Data Binding using ColumnWire</title>
+ <style type="text/css">
+ @import "../../../../dijit/themes/tundra/tundra.css";
+ @import "../../../../dojo/resources/dojo.css";
+ @import "../../../../dijit/tests/css/dijitTests.css";
+ @import "../TableContainer.css";
+ </style>
+
+ <script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+ <script type="text/javascript">
+ dojo.require("dojo.parser");
+ dojo.require("dojox.wire.ml.Invocation");
+ dojo.require("dojox.wire.ml.DataStore");
+ dojo.require("dojox.wire.ml.Transfer");
+
+ dojo.require("dijit._Widget");
+ dojo.require("dijit._Templated");
+ dojo.require("dojo.data.ItemFileReadStore");
+ dojo.require("dojox.wire");
+ dojo.require("dojox.wire.demos.TableContainer");
+
+ //Toplevel JS Object to contain a few basics for us, such as the request to pass to the store and a stub onItem function
+ // to trap on for triggering other events.
+ dataHolder = {
+ //Simple object definition to get all items and sort it by the attribute 'type'.
+ request: {onItem: function(item){}, sort: [{attribute: "type"}]},
+ //Spot to store off data values as they're generated by the declarative binding.
+ result: null
+ };
+ </script>
+</head>
+
+<body class="tundra">
+ <!--
+ The store that is queried in this demo
+ -->
+ <div dojoType="dojo.data.ItemFileReadStore"
+ jsId="DataStore1"
+ url="countries.json">
+ </div>
+
+ <!--
+ On load of the page, invoke the fetch method of the object 'DataStore1',
+ get its parameters from the JS object 'sample.request
+ -->
+ <div dojoType="dojox.wire.ml.Invocation"
+ triggerEvent="onLoad"
+ object="DataStore1" method="fetch" parameters="dataHolder.request"></div>
+
+ <!--
+ Simple container widget for creating a 'table from rows defined by an array
+ -->
+ <div dojoType="dojox.wire.demos.TableContainer" jsId="r1" headers="Name,Location Type"></div>
+
+ <!--
+ On the call of the onItem function of 'dataHolder', trigger a binding/mapping of the
+ item's attribute 'name' and 'type' attributes to specific columns in an array. Note here that since
+ sourceStore is set, it treats the arguments as items from that store and accesses the attributes
+ appropriately. In this case 'name' becomes array entry 0, type, array entry 1, and so on.
+
+ Then take the result of the data mapping and pass it into the invoke of the addRow function on the
+ TableContainer widget.
+ -->
+ <div dojoType="dojox.wire.ml.Action"
+ trigger="dataHolder.request" triggerEvent="onItem">
+ <div dojoType="dojox.wire.ml.Transfer"
+ source="arguments[0]" sourceStore="DataStore1"
+ target="dataHolder.result">
+ <div dojoType="dojox.wire.ml.ColumnWire" attribute="name"></div>
+ <div dojoType="dojox.wire.ml.ColumnWire" attribute="type"></div>
+ </div>
+ <div dojoType="dojox.wire.ml.Invocation"
+ object="r1" method="addRow" parameters='dataHolder.result'>
+ </div>
+ </div>
+</body>
+</html>
diff --git a/includes/js/dojox/wire/demos/markup/demo_ConditionalActions.html b/includes/js/dojox/wire/demos/markup/demo_ConditionalActions.html
new file mode 100644
index 0000000..ea0ca64
--- /dev/null
+++ b/includes/js/dojox/wire/demos/markup/demo_ConditionalActions.html
@@ -0,0 +1,221 @@
+<!--
+ This file demonstrates how the dojox.wire code can be used to do declarative
+ wiring of events. Specifically, it shows how you can wire actions to set values
+ across to other widgets, but only if certain conditions are met.
+-->
+<html>
+<head>
+ <title>Conditional Actions Demo</title>
+ <style type="text/css">
+
+ @import "../../../../dijit/themes/tundra/tundra.css";
+ @import "../../../../dojo/resources/dojo.css";
+ @import "../../../../dijit/tests/css/dijitTests.css";
+ @import "../TableContainer.css";
+
+ .splitView {
+ width: 90%;
+ height: 90%;
+ border: 1px solid #bfbfbf;
+ border-collapse: separate;
+ }
+
+ b {
+ float: left;
+ }
+
+ .rJustified {
+ float: right;
+ }
+
+ </style>
+
+ <script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+ <script type="text/javascript">
+ dojo.require("dojo.parser");
+ dojo.require("dojo.data.ItemFileReadStore");
+ dojo.require("dojox.wire");
+ dojo.require("dojox.wire.ml.Invocation");
+ dojo.require("dojox.wire.ml.DataStore");
+ dojo.require("dojox.wire.ml.Transfer");
+ dojo.require("dojox.wire.ml.Data");
+ dojo.require("dijit.form.TextBox");
+ dojo.require("dijit.form.CheckBox");
+ dojo.require("dijit.form.ComboBox");
+ </script>
+</head>
+
+<body class="tundra">
+
+ <!-- Layout -->
+ <font size="3"><b>Demo of Conditional Actions:</b></font><br/><br/>
+ This demo shows how you can use actions to read and set widget values, as well as have actions only occur if
+ if certain conditions are met, such as cloning values as they are typed from the billing address over to the
+ shipping address if the 'Use Same Address' checkbox is checked true.
+ <br/>
+ <br/>
+ <div dojoType="dojo.data.ItemFileReadStore" url="states.json" jsId="statesStore"></div>
+ <table width="100%">
+ <tr>
+ <td colspan="2" align="center">
+ Use Same Address: <div dojoType="dijit.form.CheckBox" id="useSameAddress" checked="true"></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <b>Billing Address</b>
+ </td>
+ <td>
+ <b>Shipping Address</b>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <b>Name:</b> <div class="rJustified" dojoType="dijit.form.TextBox" id="BillingName" name="billingname" value="" size="50"></div>
+ </td>
+ <td>
+ <b>Name:</b> <div class="rJustified" dojoType="dijit.form.TextBox" id="ShippingName" name="shippingname" value="" disabled="true" size="50"></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <b>Address 1:</b> <div class="rJustified" dojoType="dijit.form.TextBox" id="BillingAddress1" name="billingaddress1" value="" size="50"></div>
+ </td>
+ <td>
+ <b>Address 1:</b> <div class="rJustified" dojoType="dijit.form.TextBox" id="ShippingAddress1" name="shippingaddress1" value="" disabled="true" size="50"></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <b>Address 2:</b> <div class="rJustified" dojoType="dijit.form.TextBox" id="BillingAddress2" name="billingaddress2" value="" size="50"></div>
+ </td>
+ <td>
+ <b>Address 2:</b> <div class="rJustified" dojoType="dijit.form.TextBox" id="ShippingAddress2" name="shippingaddress2" value="" disabled="true" size="50"></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <b>City:</b> <div class="rJustified" dojoType="dijit.form.TextBox" id="BillingCity" name="billingcity" value="" size="50"></div>
+ </td>
+ <td>
+ <b>City:</b> <div class="rJustified" dojoType="dijit.form.TextBox" id="ShippingCity" name="shippingcity" value="" disabled="true" size="50"></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <b>State:</b> <div class="rJustified" dojoType="dijit.form.ComboBox" searchAttr="name" id="BillingState" name="billingstate" value="" store="statesStore" size="46"></div>
+ </td>
+ <td>
+ <b>State:</b> <div class="rJustified" dojoType="dijit.form.ComboBox" searchAttr="name" id="ShippingState" name="shippingstate" value="" store="statesStore" disabled="true" size="46"></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <b>Zip code:</b> <div class="rJustified" dojoType="dijit.form.TextBox" id="BillingZip" name="billingzip" value="" size="50"></div>
+ </td>
+ <td>
+ <b>Zip code:</b> <div class="rJustified" dojoType="dijit.form.TextBox" id="ShippingZip" name="shippingzip" value="" disabled="true" size="50"></div>
+ </td>
+ </tr>
+ </table>
+
+
+ <!-------------------------------- Using dojox.wire, declaratively wire up the widgets. --------------------------->
+
+ <!--
+ This is a simple data map so that the attributes we support modifying on ComboBox, TextField, etc, are lookupable.
+ since steAttribute(attr, value), replaced the single attribute setDisabled
+ -->
+ <div dojoType="dojox.wire.ml.Data"
+ id="attributesMap">
+ <div dojoType="dojox.wire.ml.DataProperty"
+ name="disabled"
+ value="disabled"></div>
+ </div>
+
+
+ <!--
+ Enable/disable the Right hand side of the shipping address view based on the checkbox events.
+ -->
+ <div dojoType="dojox.wire.ml.Action"
+ trigger="useSameAddress"
+ triggerEvent="setChecked">
+ <!--
+ Trigger a setting of the Shipping fields' input state based on the state of the checkbox.
+ -->
+ <div dojoType="dojox.wire.ml.Invocation" object="ShippingName" method="setAttribute" parameters="attributesMap.disabled, arguments[0]"></div>
+ <div dojoType="dojox.wire.ml.Invocation" object="ShippingAddress1" method="setAttribute" parameters="attributesMap.disabled, arguments[0]"></div>
+ <div dojoType="dojox.wire.ml.Invocation" object="ShippingAddress2" method="setAttribute" parameters="attributesMap.disabled, arguments[0]"></div>
+ <div dojoType="dojox.wire.ml.Invocation" object="ShippingCity" method="setAttribute" parameters="attributesMap.disabled, arguments[0]"></div>
+ <div dojoType="dojox.wire.ml.Invocation" object="ShippingState" method="setAttribute" parameters="attributesMap.disabled, arguments[0]"></div>
+ <div dojoType="dojox.wire.ml.Invocation" object="ShippingZip" method="setAttribute" parameters="attributesMap.disabled, arguments[0]"></div>
+ </div>
+
+ <!--
+ Clone the values of form fields while typing based on the setting of the checkbox.
+ -->
+ <div dojoType="dojox.wire.ml.Action"
+ trigger="BillingName"
+ triggerEvent="onkeyup">
+ <div dojoType="dojox.wire.ml.ActionFilter" required="useSameAddress.checked" requiredValue="true" type="boolean"></div>
+ <div dojoType="dojox.wire.ml.Transfer" source="BillingName.value" target="ShippingName.value"></div>
+ </div>
+ <div dojoType="dojox.wire.ml.Action"
+ trigger="BillingAddress1"
+ triggerEvent="onkeyup">
+ <div dojoType="dojox.wire.ml.ActionFilter" required="useSameAddress.checked" requiredValue="true" type="boolean"></div>
+ <div dojoType="dojox.wire.ml.Transfer" source="BillingAddress1.value" target="ShippingAddress1.value"></div>
+ </div>
+ <div dojoType="dojox.wire.ml.Action"
+ trigger="BillingAddress2"
+ triggerEvent="onkeyup">
+ <div dojoType="dojox.wire.ml.ActionFilter" required="useSameAddress.checked" requiredValue="true" type="boolean"></div>
+ <div dojoType="dojox.wire.ml.Transfer" source="BillingAddress2.value" target="ShippingAddress2.value"></div>
+ </div>
+ <div dojoType="dojox.wire.ml.Action"
+ trigger="BillingCity"
+ triggerEvent="onkeyup">
+ <div dojoType="dojox.wire.ml.ActionFilter" required="useSameAddress.checked" requiredValue="true" type="boolean"></div>
+ <div dojoType="dojox.wire.ml.Transfer" source="BillingCity.value" target="ShippingCity.value"></div>
+ </div>
+ <div dojoType="dojox.wire.ml.Action"
+ trigger="BillingState"
+ triggerEvent="onChange">
+ <div dojoType="dojox.wire.ml.ActionFilter" required="useSameAddress.checked" requiredValue="true" type="boolean"></div>
+ <div dojoType="dojox.wire.ml.Transfer" source="BillingState.value" target="ShippingState.value"></div>
+ </div>
+
+ <div dojoType="dojox.wire.ml.Action"
+ trigger="BillingZip"
+ triggerEvent="onkeyup">
+ <div dojoType="dojox.wire.ml.ActionFilter" required="useSameAddress.checked" requiredValue="true" type="boolean"></div>
+ <div dojoType="dojox.wire.ml.Transfer" source="BillingZip.value" target="ShippingZip.value"></div>
+ </div>
+
+
+ <!--
+ Clone the values of form fields from billing over to shipping over if the
+ useSameAddress checkbox is set back to true.
+ -->
+ <div dojoType="dojox.wire.ml.Action"
+ trigger="useSameAddress"
+ triggerEvent="setChecked">
+ <div dojoType="dojox.wire.ml.ActionFilter" required="arguments[0]" requiredValue="true" type="boolean"></div>
+
+ <!--
+ Note that this uses the basic 'property' form of copying the property over and setting it. The Wire
+ code supports both getX and setX functions of setting a property as well as direct access. It first looks
+ for the getX/setX functions and if present, uses them. If missing, it will just do direct access. Because
+ of the standard getValue/setValue API of dijit form widgets, transfers work well and are compact.
+ -->
+ <div dojoType="dojox.wire.ml.Transfer" source="BillingName.value" target="ShippingName.value"></div>
+ <div dojoType="dojox.wire.ml.Transfer" source="BillingAddress1.value" target="ShippingAddress1.value"></div>
+ <div dojoType="dojox.wire.ml.Transfer" source="BillingAddress2.value" target="ShippingAddress2.value"></div>
+ <div dojoType="dojox.wire.ml.Transfer" source="BillingCity.value" target="ShippingCity.value"></div>
+ <div dojoType="dojox.wire.ml.Transfer" source="BillingState.value" target="ShippingState.value"></div>
+ <div dojoType="dojox.wire.ml.Transfer" source="BillingZip.value" target="ShippingZip.value"></div>
+ </div>
+
+</body>
+</html>
diff --git a/includes/js/dojox/wire/demos/markup/demo_FlickrStoreWire.html b/includes/js/dojox/wire/demos/markup/demo_FlickrStoreWire.html
new file mode 100644
index 0000000..54068a9
--- /dev/null
+++ b/includes/js/dojox/wire/demos/markup/demo_FlickrStoreWire.html
@@ -0,0 +1,281 @@
+<!--
+ This file is a demo of the FlickrStore, a simple wrapper to the public feed service
+ of Flickr. This just does very basic queries against Flickr and loads the results
+ into a list viewing widget.
+-->
+<html>
+<head>
+ <title>Demo of FlickrStore</title>
+ <style type="text/css">
+
+ @import "../../../../dijit/themes/tundra/tundra.css";
+ @import "../../../../dojo/resources/dojo.css";
+ @import "../../../../dijit/tests/css/dijitTests.css";
+ @import "./flickrDemo.css";
+ </style>
+
+ <script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+ <script type="text/javascript">
+ dojo.require("dojo.parser");
+ dojo.require("dijit.form.TextBox");
+ dojo.require("dijit.form.Button");
+ dojo.require("dijit.form.ComboBox");
+ dojo.require("dijit.form.NumberSpinner");
+ dojo.require("dojox.data.FlickrStore");
+ dojo.require("dojox.wire.ml.Invocation");
+ dojo.require("dojox.wire.ml.Transfer");
+ dojo.require("dojox.wire.ml.Data");
+ dojo.require("dojox.wire");
+ dojo.require("dojox.data.demos.widgets.FlickrViewList");
+ dojo.require("dojox.data.demos.widgets.FlickrView");
+
+ //Toplevel JS Object to contain a few basics for us, such as the request to pass to the store and a stub onItem and onComplete function
+ // to trap on for triggering other events.
+ var dataHolder = {
+ //Simple stub datastore request
+ request: {query: {}, onItem: function(item, req){}, onComplete: function(items, req){}},
+
+ //Spot to store off data values as they're generated by the declarative binding.
+ result: null
+ };
+
+ //Function to convert the input from a widget into a comma separated list.
+ //that is the format of the store parameter.
+ var tagsInputConverter = function(tags){
+ if(tags && tags !== ""){
+ var tagsArray = tags.split(" ");
+ tags = "";
+ for(var i = 0; i < tagsArray.length; i++){
+ tags = tags + tagsArray[i];
+ if(i < (tagsArray.length - 1)){
+ tags += ","
+ }
+ }
+ }
+ return tags
+ }
+
+ </script>
+</head>
+
+<body class="tundra">
+ <h1>
+ DEMO: FlickrStore Search
+ </h1>
+ <hr>
+ <h3>
+ Description:
+ </h3>
+ <p>
+ This simple demo shows how services, such as Flickr, can be wrapped by the datastore API. In this demo, you can search public
+ Flickr images through a simple FlickrStore by specifying a series of tags (separated by spaces) to search on. The results
+ will be displayed below the search box. This demo is the same as the example demo provided in dojox/data/demos/demo_FlickrStore.html,
+ except that all the interactions are implemented via Wire instead of a script that runs at dojo.addOnLoad().
+ </p>
+ <p>
+ For fun, search on the 3dny tag!
+ </p>
+
+ <blockquote>
+
+ <!--
+ Layout.
+ -->
+ <table>
+ <tbody>
+ <tr>
+ <td>
+ <b>Status:</b>
+ </td>
+ <td>
+ <div dojoType="dijit.form.TextBox" size="50" id="status" jsId="statusWidget" disabled="true"></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <b>ID:</b>
+ </td>
+ <td>
+ <div dojoType="dijit.form.TextBox" size="50" id="userid" jsId="idWidget"></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <b>Tags:</b>
+ </td>
+ <td>
+ <div dojoType="dijit.form.TextBox" size="50" id="tags" jsId="tagsWidget" value="3dny"></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <b>Tagmode:</b>
+ </td>
+ <td>
+ <select id="tagmode"
+ jsId="tagmodeWidget"
+ dojoType="dijit.form.ComboBox"
+ autocomplete="false"
+ value="any"
+ >
+ <option>any</option>
+ <option>all</option>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <b>Number of Pictures:</b>
+ </td>
+ <td>
+ <div
+ id="count"
+ jsId="countWidget"
+ dojoType="dijit.form.NumberSpinner"
+ value="20"
+ constraints="{min:1,max:20,places:0}"
+ ></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ </td>
+ <td>
+ <div dojoType="dijit.form.Button" label="Search" id="searchButton" jsId="searchButtonWidget"></div>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </blockquote>
+ <!--
+ The store instance used by this demo.
+ -->
+ <div dojoType="dojox.data.FlickrStore" jsId="flickrStore" label="title"></div>
+ <div dojoType="dojox.data.demos.widgets.FlickrViewList" id="flickrViews" jsId="flickrViewsWidget"></div>
+
+ <!-------------------------------- Using dojox.wire, declaratively wire up the widgets. --------------------------->
+
+
+ <!--
+ This is an example of using the declarative data value definition.
+ These are effectively declarative variables to act as placeholders
+ for data values.
+ -->
+ <div dojoType="dojox.wire.ml.Data"
+ id="messageData"
+ jsId="messageData">
+ <div dojoType="dojox.wire.ml.DataProperty"
+ name="processingStart"
+ value="PROCESSING REQUEST">
+ </div>
+ <div dojoType="dojox.wire.ml.DataProperty"
+ name="processingDone"
+ value="PROCESSING COMPLETE">
+ </div>
+ </div>
+
+
+ <!--
+ When the search button is clicked, do the following in order:
+ 1.) Map the widget values over to the request properties.
+ 2.) Clear existing rows from table,
+ 3.) Set the status to processing
+ 4.) Invoke the fetch to repopulate the table.
+ -->
+ <div dojoType="dojox.wire.ml.Action"
+ trigger="searchButtonWidget"
+ triggerEvent="onClick">
+
+ <!--
+ Read in the values from the widgets and bind them to the appropriate data locations
+ For basic properties, you could use transfer directly, but since the text boxes are
+ designed to be accessed through getValue/setValue, it's better to do these as
+ Invocations on widget methods.
+ -->
+ <div dojoType="dojox.wire.ml.Invocation"
+ object="idWidget"
+ method="getValue"
+ result="dataHolder.request.query.id">
+ </div>
+
+
+ <!--
+ For the tags, we need to get the value and then perform a conversion on the result
+ This is done by doing an invoke, then a transfer through a converter.
+ -->
+ <div dojoType="dojox.wire.ml.Invocation"
+ object="tagsWidget"
+ method="getValue"
+ result="dataHolder.request.query.tags">
+ </div>
+ <div dojoType="dojox.wire.ml.Transfer"
+ source="dataHolder.request.query.tags"
+ target="dataHolder.request.query.tags"
+ converter="tagsInputConverter">
+ </div>
+
+ <div dojoType="dojox.wire.ml.Invocation"
+ object="tagmodeWidget"
+ method="getValue"
+ result="dataHolder.request.query.tagmode">
+ </div>
+
+ <div dojoType="dojox.wire.ml.Invocation"
+ object="countWidget"
+ method="getValue"
+ result="dataHolder.request.count">
+ </div>
+
+
+ <!-- Now invoke the actions in order. -->
+ <div dojoType="dojox.wire.ml.Invocation" object="flickrViewsWidget" method="clearList"></div>
+ <div dojoType="dojox.wire.ml.Invocation" object="statusWidget" method="setValue" parameters="messageData.processingStart"></div>
+ <div dojoType="dojox.wire.ml.Invocation" object="flickrStore" method="fetch" parameters="dataHolder.request"></div>
+ </div>
+
+ <!--
+ When the fetch processing finishes (onComplete is called), then set status to complete.
+ -->
+ <div dojoType="dojox.wire.ml.Action"
+ trigger="dataHolder.request"
+ triggerEvent="onComplete">
+ <div dojoType="dojox.wire.ml.Invocation" object="statusWidget" method="setValue" parameters="messageData.processingDone"></div>
+ </div>
+
+
+ <!--
+ On the call of the onItem function of 'dataHolder', trigger a binding/mapping of the
+ item's attributes to the requires parameters that are passed into addView. In this case
+ FlikrItemAttribute -> viewItemParam
+ title title
+ imageUrlSmall iconUrl
+ imageUrl imageUrl
+ author author
+
+ Then take the result of the data mapping and pass it into the invoke of the addView function on the
+ FlickerViews widget.
+ -->
+ <div dojoType="dojox.wire.ml.Action"
+ trigger="dataHolder.request" triggerEvent="onItem">
+ <div dojoType="dojox.wire.ml.Transfer"
+ source="arguments[0]" sourceStore="flickrStore"
+ target="dataHolder.result">
+ <!--
+ Map the attributes of the items to the property name defined
+ in the wire on the object in the target
+ -->
+ <div dojoType="dojox.wire.ml.ChildWire"
+ name="title" attribute="title"></div>
+ <div dojoType="dojox.wire.ml.ChildWire"
+ name="imageUrl" attribute="imageUrl"></div>
+ <div dojoType="dojox.wire.ml.ChildWire"
+ name="iconUrl" attribute="imageUrlSmall"></div>
+ <div dojoType="dojox.wire.ml.ChildWire"
+ name="author" attribute="author"></div>
+ </div>
+ <div dojoType="dojox.wire.ml.Invocation"
+ object="flickrViewsWidget" method="addView" parameters='dataHolder.result'>
+ </div>
+ </div>
+</body>
+</html>
diff --git a/includes/js/dojox/wire/demos/markup/demo_TopicWiring.html b/includes/js/dojox/wire/demos/markup/demo_TopicWiring.html
new file mode 100644
index 0000000..e091e8b
--- /dev/null
+++ b/includes/js/dojox/wire/demos/markup/demo_TopicWiring.html
@@ -0,0 +1,78 @@
+<!--
+ This file demonstrates how the dojox.wire code can be used to do declarative
+ wiring of events. Specifically, it shows how you can publish and subscribe
+ to topics. In this case the setting of a value on one textbox triggers a
+ publish of that value to a topic. Another invoke is wired to fire when
+ values are published to that topic which is then displayed in another
+ textbox.
+-->
+<html>
+<head>
+ <title>Sample Topic Wiring</title>
+ <style type="text/css">
+
+ @import "../../../../dijit/themes/tundra/tundra.css";
+ @import "../../../../dojo/resources/dojo.css";
+ @import "../../../../dijit/tests/css/dijitTests.css";
+ @import "../TableContainer.css";
+
+ .splitView {
+ width: 90%;
+ height: 90%;
+ border: 1px solid #bfbfbf;
+ border-collapse: separate;
+ }
+ </style>
+
+ <script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+ <script type="text/javascript">
+ dojo.require("dojo.parser");
+ dojo.require("dojox.wire");
+ dojo.require("dojox.wire.ml.Invocation");
+ dojo.require("dojox.wire.ml.DataStore");
+ dojo.require("dojox.wire.ml.Transfer");
+ dojo.require("dojox.wire.ml.Data");
+
+ dojo.require("dijit.form.TextBox");
+ </script>
+</head>
+
+<body class="tundra">
+
+ <!-- Layout -->
+ <font size="3"><b>Demo of Topic Wiring</b></font><br/><br/>
+ This demo shows how you can wire events to publish to a topic as well as recieve topic events
+ <br/>
+ <br/>
+ <table>
+ <tr>
+ <td>
+ <div dojoType="dijit.form.TextBox" jsId="inputField" value="" size="50"></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <div dojoType="dijit.form.TextBox" jsId="targetField1" value="" disabled="true" size="50"></div>
+ </td>
+ </tr>
+ </table>
+
+
+ <!-------------------------------- Using dojox.wire, declaratively wire up the widgets. --------------------------->
+
+ <!--
+ Whenever a key is entered into the textbox, publish the value of it to a topic.
+ -->
+ <div dojoType="dojox.wire.ml.Action"
+ id="action1"
+ trigger="inputField"
+ triggerEvent="onkeyup">
+ <div dojoType="dojox.wire.ml.Invocation" topic="sampleTopic" parameters="inputField.value"></div>
+ </div>
+
+ <!--
+ Whenever a value is published to a topic, set it as the value of the textbox by calling the setValue function.
+ -->
+ <div dojoType="dojox.wire.ml.Invocation" triggerTopic="sampleTopic" object="targetField1" method="setValue" parameters="arguments[0]"></div>
+</body>
+</html>
diff --git a/includes/js/dojox/wire/demos/markup/flickrDemo.css b/includes/js/dojox/wire/demos/markup/flickrDemo.css
new file mode 100644
index 0000000..793d1c6
--- /dev/null
+++ b/includes/js/dojox/wire/demos/markup/flickrDemo.css
@@ -0,0 +1,29 @@
+.flickrView {
+ padding: 3 3 3 3;
+ border-width: 1px;
+ border-style: solid;
+ border-color: #000000;
+ border-collapse: separate;
+ width: 100%;
+}
+.flickrView th {
+ text-align: left;
+}
+.flickrView tr {
+ padding: 3 3 3 3;
+ border-width: 1px;
+ border-style: solid;
+ border-color: #000000;
+}
+.flickrView tr td {
+ padding: 3 3 3 3;
+ border-width: 1px;
+ border-style: solid;
+ border-color: #000000;
+}
+.flickrView {
+ background-color: #EFEFEF;
+}
+.flickrTitle {
+ background-color: #CCCCCC;
+}
diff --git a/includes/js/dojox/wire/demos/markup/flickrDemo.css.commented.css b/includes/js/dojox/wire/demos/markup/flickrDemo.css.commented.css
new file mode 100644
index 0000000..7e75a5d
--- /dev/null
+++ b/includes/js/dojox/wire/demos/markup/flickrDemo.css.commented.css
@@ -0,0 +1,35 @@
+.flickrView {
+ padding: 3 3 3 3;
+ border-width: 1px;
+ border-style: solid;
+ border-color: #000000;
+ border-collapse: separate;
+ width: 100%;
+}
+
+.flickrView th {
+ text-align: left;
+}
+
+.flickrView tr {
+ padding: 3 3 3 3;
+ border-width: 1px;
+ border-style: solid;
+ border-color: #000000;
+}
+
+.flickrView tr td {
+ padding: 3 3 3 3;
+ border-width: 1px;
+ border-style: solid;
+ border-color: #000000;
+}
+
+.flickrView {
+ background-color: #EFEFEF;
+}
+
+.flickrTitle {
+ background-color: #CCCCCC;
+}
+
diff --git a/includes/js/dojox/wire/demos/markup/states.json b/includes/js/dojox/wire/demos/markup/states.json
new file mode 100644
index 0000000..bdaa609
--- /dev/null
+++ b/includes/js/dojox/wire/demos/markup/states.json
@@ -0,0 +1,56 @@
+{"identifier":"abbreviation",
+"label": "label",
+"items": [
+ {"name":"Alabama", "label":"Alabama","abbreviation":"AL"},
+ {"name":"Alaska", "label":"Alaska","abbreviation":"AK"},
+ {"name":"American Samoa", "label":"American Samoa","abbreviation":"AS"},
+ {"name":"Arizona", "label":"Arizona","abbreviation":"AZ"},
+ {"name":"Arkansas", "label":"Arkansas","abbreviation":"AR"},
+ {"name":"California", "label":"California","abbreviation":"CA"},
+ {"name":"Colorado", "label":"Colorado","abbreviation":"CO"},
+ {"name":"Connecticut", "label":"Connecticut","abbreviation":"CT"},
+ {"name":"Delaware", "label":"Delaware","abbreviation":"DE"},
+ {"name":"Florida", "label":"Florida","abbreviation":"FL"},
+ {"name":"Georgia", "label":"Georgia","abbreviation":"GA"},
+ {"name":"Hawaii", "label":"Hawaii","abbreviation":"HI"},
+ {"name":"Idaho", "label":"Idaho","abbreviation":"ID"},
+ {"name":"Illinois", "label":"Illinois","abbreviation":"IL"},
+ {"name":"Indiana", "label":"Indiana","abbreviation":"IN"},
+ {"name":"Iowa", "label":"Iowa","abbreviation":"IA"},
+ {"name":"Kansas", "label":"Kansas","abbreviation":"KS"},
+ {"name":"Kentucky", "label":"Kentucky","abbreviation":"KY"},
+ {"name":"Louisiana", "label":"Louisiana","abbreviation":"LA"},
+ {"name":"Maine", "label":"Maine","abbreviation":"ME"},
+ {"name":"Marshall Islands", "label":"Marshall Islands","abbreviation":"MH"},
+ {"name":"Maryland", "label":"Maryland","abbreviation":"MD"},
+ {"name":"Massachusetts", "label":"Massachusetts","abbreviation":"MA"},
+ {"name":"Michigan", "label":"Michigan","abbreviation":"MI"},
+ {"name":"Minnesota", "label":"Minnesota","abbreviation":"MN"},
+ {"name":"Mississippi", "label":"Mississippi","abbreviation":"MS"},
+ {"name":"Missouri", "label":"Missouri","abbreviation":"MO"},
+ {"name":"Montana", "label":"Montana","abbreviation":"MT"},
+ {"name":"Nebraska", "label":"Nebraska","abbreviation":"NE"},
+ {"name":"Nevada", "label":"Nevada","abbreviation":"NV"},
+ {"name":"New Hampshire", "label":"New Hampshire","abbreviation":"NH"},
+ {"name":"New Jersey", "label":"New Jersey","abbreviation":"NJ"},
+ {"name":"New Mexico", "label":"New Mexico","abbreviation":"NM"},
+ {"name":"New York", "label":"New York","abbreviation":"NY"},
+ {"name":"North Carolina", "label":"North Carolina","abbreviation":"NC"},
+ {"name":"North Dakota", "label":"North Dakota","abbreviation":"ND"},
+ {"name":"Ohio", "label":"Ohio","abbreviation":"OH"},
+ {"name":"Oklahoma", "label":"Oklahoma","abbreviation":"OK"},
+ {"name":"Oregon", "label":"Oregon","abbreviation":"OR"},
+ {"name":"Pennsylvania", "label":"Pennsylvania","abbreviation":"PA"},
+ {"name":"Rhode Island", "label":"Rhode Island","abbreviation":"RI"},
+ {"name":"South Carolina", "label":"South Carolina","abbreviation":"SC"},
+ {"name":"South Dakota", "label":"South Dakota","abbreviation":"SD"},
+ {"name":"Tennessee", "label":"Tennessee","abbreviation":"TN"},
+ {"name":"Texas", "label":"Texas","abbreviation":"TX"},
+ {"name":"Utah", "label":"Utah","abbreviation":"UT"},
+ {"name":"Vermont", "label":"Vermont","abbreviation":"VT"},
+ {"name":"Virginia", "label":"Virginia","abbreviation":"VA"},
+ {"name":"Washington", "label":"Washington","abbreviation":"WA"},
+ {"name":"West Virginia", "label":"West Virginia","abbreviation":"WV"},
+ {"name":"Wisconsin", "label":"Wisconsin","abbreviation":"WI"},
+ {"name":"Wyoming", "label":"Wyoming","abbreviation":"WY"}
+]} \ No newline at end of file
diff --git a/includes/js/dojox/wire/ml/Action.js b/includes/js/dojox/wire/ml/Action.js
new file mode 100644
index 0000000..637de41
--- /dev/null
+++ b/includes/js/dojox/wire/ml/Action.js
@@ -0,0 +1,225 @@
+if(!dojo._hasResource["dojox.wire.ml.Action"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.wire.ml.Action"] = true;
+dojo.provide("dojox.wire.ml.Action");
+dojo.provide("dojox.wire.ml.ActionFilter");
+
+dojo.require("dijit._Widget");
+dojo.require("dijit._Container");
+dojo.require("dojox.wire.Wire");
+dojo.require("dojox.wire.ml.util");
+
+dojo.declare("dojox.wire.ml.Action", [dijit._Widget, dijit._Container], {
+ // summary:
+ // A base widget to "run" a task on an event or a topic
+ // description:
+ // This widget represents a controller task to be run when an event
+ // (a function) or a topic is issued.
+ // Sub-classes must implement _run() method to implement their tasks.
+ // 'trigger' specifies an event scope, an ID of a widget or an DOM
+ // element, or its property with the optional dotted notation.
+ // If this widget has child ActionFilter widgets, their filter()
+ // methods are called with the arguments to the event or the topic.
+ // If one of filter() methods returns false, run() won't be invoked.
+ // This widget also can serve as a composite task to run child
+ // Actions on an event or a topic specified to this widget.
+ // trigger:
+ // An event scope
+ // triggerEvent:
+ // An event (function) name
+ // triggerTopic:
+ // A topic name
+ trigger: "",
+ triggerEvent: "",
+ triggerTopic: "",
+
+ postCreate: function(){
+ // summary:
+ // Call _connect()
+ // description:
+ // See _connect().
+ this._connect();
+ },
+
+ _connect: function(){
+ // summary:
+ // Connect run() method to an event or a topic
+ // description:
+ // If 'triggerEvent' and 'trigger' are specified, connect() is
+ // used to set up run() to be called on the event.
+ // If 'triggerTopic' is specified, subscribe() is used to set up
+ // run() to be called on the topic.
+ if(this.triggerEvent){
+ if(this.trigger){
+ var scope = dojox.wire.ml._getValue(this.trigger);
+ if(scope){
+ if(!scope[this.triggerEvent]){
+ // set a dummy function for an anonymous object
+ scope[this.triggerEvent] = function(){};
+ }
+ this._triggerHandle = dojo.connect(scope, this.triggerEvent, this, "run");
+ }
+ }else{
+ var event = this.triggerEvent.toLowerCase();
+ if(event == "onload"){
+ var self = this;
+ dojo.addOnLoad(function(){
+ self._run.apply(self, arguments);
+ });
+ }
+ }
+ }else if(this.triggerTopic){
+ this._triggerHandle = dojo.subscribe(this.triggerTopic, this, "run");
+ }
+ },
+
+ _disconnect: function(){
+ // summary:
+ // Disconnect run() method from an event or a topic
+ // description:
+ // If 'triggerEvent' and 'trigger' are specified, disconnect() is
+ // used to set up run() not to be called on the event.
+ // If 'triggerTopic' is specified, unsubscribe() is used to set up
+ // run() not to be called on the topic.
+ if(this._triggerHandle){
+ if(this.triggerTopic){
+ dojo.unsubscribe(this.triggerTopic, this._triggerHandle);
+ }else{
+ dojo.disconnect(this._triggerHandle);
+ }
+ }
+ },
+
+ run: function(){
+ // summary:
+ // Run a task
+ // description:
+ // This method calls filter() method of child ActionFilter
+ // widgets.
+ // If one of them returns false, this method returns.
+ // Otherwise, _run() method is called.
+ var children = this.getChildren();
+ for(var i in children){
+ var child = children[i];
+ if(child instanceof dojox.wire.ml.ActionFilter){
+ if(!child.filter.apply(child, arguments)){
+ return;
+ }
+ }
+ }
+ this._run.apply(this, arguments);
+ },
+
+ _run: function(){
+ // summary:
+ // Call run() methods of child Action widgets
+ // description:
+ // If this widget has child Action widgets, their run() methods
+ // are called.
+ var children = this.getChildren();
+ for(var i in children){
+ var child = children[i];
+ if(child instanceof dojox.wire.ml.Action){
+ child.run.apply(child, arguments);
+ }
+ }
+ },
+
+ uninitialize: function(){
+ // summary:
+ // Over-ride of base widget unitialize function to do some connection cleanup.
+ this._disconnect();
+ return true;
+ }
+});
+
+dojo.declare("dojox.wire.ml.ActionFilter", dijit._Widget, {
+ // summary:
+ // A widget to define a filter for the parent Action to run
+ // description:
+ // This base class checks a required property specified with
+ // 'required' attribute.
+ // If 'message' is specified, the message is set to a property
+ // specified with 'error'.
+ // Subclasses may implement their own filter() method.
+ // required:
+ // A property required
+ // requiredValue:
+ // Optional. A specific value the property is required to have. If this isn't provided
+ // than any non-false/non-null value of the required propery will cause this filter
+ // to pass.
+ // type:
+ // Optional. A specific type to compare the values as (if requiredValue is set)
+ // Valid values for type are boolean, int, string. Default is string.
+ // message:
+ // An error message to emit if the filter doesn't execute due to property mismatch.
+ // error:
+ // A property to store an error due to property mismatch.
+ required: "",
+ requiredValue: "",
+ type: "",
+ message: "",
+ error: "",
+
+
+ filter: function(){
+ // summary:
+ // Check if a required property is specified. Also, if provided, check to see
+ // if the required property contains a specific value.
+ // description:
+ // If a value is undefined for a property, specified with
+ // 'required', this method returns false.
+ // If the value for a property is defined, but there isn't a requiredValue for it
+ // then any non-false value will cause the method to return true.
+ // if requiredValue is set, then filter compares that value with the value from
+ // the required property and returns true if and only if they match.
+ // The type option just allows for a way to convert the required property values
+ // into a proper form for comparison (boolean, number, etc).
+ // If 'message' is specified, it is set to a proeprty specified
+ // with 'error' or shown with alert().
+ // If 'required' starts with "arguments", a property of
+ // the method arguments are checked.
+ // returns:
+ // True if a required property is specified (and if requiredValue is specified,
+ // that they match), otherwise false
+ if(this.required === ""){
+ return true; //Boolean
+ }else{
+ var value = dojox.wire.ml._getValue(this.required, arguments);
+ if(this.requiredValue === ""){
+ //Just see if there's a value, nothing to compare it to.
+ if(value){
+ return true; //Boolean
+ }
+ }else{
+ //See if we need to type convert.
+ var reqValue = this.requiredValue;
+ if(this.type !== ""){
+ var lType = this.type.toLowerCase();
+ if(lType === "boolean"){
+ if(reqValue.toLowerCase() === "false"){
+ reqValue = false;
+ }else{
+ reqValue = true;
+ }
+ }else if(lType === "number"){
+ reqValue = parseInt(reqValue, 10);
+ }
+ }
+ if(value === reqValue){
+ return true; //boolean
+ }
+ }
+ }
+
+ if(this.message){
+ if(this.error){
+ dojox.wire.ml._setValue(this.error, this.message);
+ }else{
+ alert(this.message);
+ }
+ }
+ return false; //Boolean
+ }
+});
+
+}
diff --git a/includes/js/dojox/wire/ml/Data.js b/includes/js/dojox/wire/ml/Data.js
new file mode 100644
index 0000000..71ab0ad
--- /dev/null
+++ b/includes/js/dojox/wire/ml/Data.js
@@ -0,0 +1,143 @@
+if(!dojo._hasResource["dojox.wire.ml.Data"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.wire.ml.Data"] = true;
+dojo.provide("dojox.wire.ml.Data");
+dojo.provide("dojox.wire.ml.DataProperty");
+
+dojo.require("dijit._Widget");
+dojo.require("dijit._Container");
+dojo.require("dojox.wire.ml.util");
+
+dojo.declare("dojox.wire.ml.Data", [dijit._Widget, dijit._Container], {
+ // summary:
+ // A widget for a data object
+ // description:
+ // This widget represents an object with '_properties' property.
+ // If child 'DataProperty' widgets exist, they are used to initialize
+ // propertiy values of '_properties' object.
+
+ startup: function(){
+ // summary:
+ // Call _initializeProperties()
+ // description:
+ // See _initializeProperties().
+ this._initializeProperties();
+ },
+
+ _initializeProperties: function(/*Boolean*/reset){
+ // summary:
+ // Initialize a data object
+ // description:
+ // If this widget has child DataProperty widgets, their getValue()
+ // methods are called and set the return value to a property
+ // specified by 'name' attribute of the child widgets.
+ // reset:
+ // A boolean to reset current properties
+ if(!this._properties || reset){
+ this._properties = {};
+ }
+ var children = this.getChildren();
+ for(var i in children){
+ var child = children[i];
+ if((child instanceof dojox.wire.ml.DataProperty) && child.name){
+ this.setPropertyValue(child.name, child.getValue());
+ }
+ }
+ },
+
+ getPropertyValue: function(/*String*/property){
+ // summary:
+ // Return a property value
+ // description:
+ // This method returns the value of a property, specified with
+ // 'property' argument, in '_properties' object.
+ // property:
+ // A property name
+ // returns:
+ // A property value
+ return this._properties[property]; //anything
+ },
+
+ setPropertyValue: function(/*String*/property, /*anything*/value){
+ // summary:
+ // Store a property value
+ // description:
+ // This method stores 'value' as a property, specified with
+ // 'property' argument, in '_properties' object.
+ // property:
+ // A property name
+ // value:
+ // A property value
+ this._properties[property] = value;
+ }
+});
+
+dojo.declare("dojox.wire.ml.DataProperty", [dijit._Widget, dijit._Container], {
+ // summary:
+ // A widget to define a data property
+ // description:
+ // Attributes of this widget are used to add a property to the parent
+ // Data widget.
+ // 'type' attribute specifies one of "string", "number", "boolean",
+ // "array", "object" and "element" (DOM Element)
+ // (default to "string").
+ // If 'type' is "array" or "object", child DataProperty widgets are
+ // used to initialize the array elements or the object properties.
+ // name:
+ // A property name
+ // type:
+ // A property type name
+ // value:
+ // A property value
+ name: "",
+ type: "",
+ value: "",
+
+ getValue: function(){
+ // summary:
+ // Returns a property value
+ // description:
+ // If 'type' is specified, 'value' attribute is converted to
+ // the specified type and returned.
+ // Otherwise, 'value' attribute is returned as is.
+ // returns:
+ // A property value
+ var value = this.value;
+ if(this.type){
+ if(this.type == "number"){
+ value = parseInt(value);
+ }else if(this.type == "boolean"){
+ value = (value == "true");
+ }else if(this.type == "array"){
+ value = [];
+ var children = this.getChildren();
+ for(var i in children){
+ var child = children[i];
+ if(child instanceof dojox.wire.ml.DataProperty){
+ value.push(child.getValue());
+ }
+ }
+ }else if(this.type == "object"){
+ value = {};
+ var children = this.getChildren();
+ for(var i in children){
+ var child = children[i];
+ if((child instanceof dojox.wire.ml.DataProperty) && child.name){
+ value[child.name] = child.getValue();
+ }
+ }
+ }else if(this.type == "element"){
+ value = new dojox.wire.ml.XmlElement(value);
+ var children = this.getChildren();
+ for(var i in children){
+ var child = children[i];
+ if((child instanceof dojox.wire.ml.DataProperty) && child.name){
+ value.setPropertyValue(child.name, child.getValue());
+ }
+ }
+ }
+ }
+ return value; //anything
+ }
+});
+
+}
diff --git a/includes/js/dojox/wire/ml/DataStore.js b/includes/js/dojox/wire/ml/DataStore.js
new file mode 100644
index 0000000..e366d05
--- /dev/null
+++ b/includes/js/dojox/wire/ml/DataStore.js
@@ -0,0 +1,116 @@
+if(!dojo._hasResource["dojox.wire.ml.DataStore"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.wire.ml.DataStore"] = true;
+dojo.provide("dojox.wire.ml.DataStore");
+
+dojo.require("dijit._Widget");
+dojo.require("dojox.wire._base");
+
+dojo.declare("dojox.wire.ml.DataStore", dijit._Widget, {
+ // summary:
+ // A widget for a data store
+ // description:
+ // This widget represents a data store of 'storeClass' attribute.
+ // storeClass:
+ // A class name of a data store
+ storeClass: "",
+
+ postCreate: function(){
+ // summary:
+ // Call _createStore()
+ // description:
+ // See _createStore().
+ this.store = this._createStore();
+ },
+
+ _createStore: function(){
+ // summary:
+ // Create a data store
+ // desription:
+ // A data store of 'storeClass' is created with arguments
+ // specified with attributes.
+ // returns:
+ // A data store
+ if(!this.storeClass){
+ return null; //null
+ }
+ var storeClass = dojox.wire._getClass(this.storeClass);
+ if(!storeClass){
+ return null; //null
+ }
+ var args = {};
+ var attributes = this.domNode.attributes;
+ for(var i = 0; i < attributes.length; i++){
+ var a = attributes.item(i);
+ if(a.specified && !this[a.nodeName]){
+ args[a.nodeName] = a.nodeValue;
+ }
+ }
+ return new storeClass(args); //Object
+ },
+
+ getFeatures: function(){
+ // summary:
+ // Call getFeatures() method of a data store
+ // description:
+ // See dojo.data.api.Read.getFeatures().
+ // returns:
+ // A features object
+ return this.store.getFeatures(); //Object
+ },
+
+ fetch: function(/*Object*/request){
+ // summary:
+ // Call fetch() method of a data store
+ // description:
+ // See dojo.data.api.Read.fetch().
+ // request:
+ // A request object
+ // returns:
+ // A request object
+ return this.store.fetch(request); //Object
+ },
+
+ save: function(/*Object*/args){
+ // summary:
+ // Call save() method of a data store
+ // description:
+ // See dojo.data.api.Write.save().
+ // args:
+ // A save arguments object
+ this.store.save(args);
+ },
+
+ newItem: function(/*Object*/args){
+ // summary:
+ // Call newItem() method of a data store
+ // description:
+ // See dojo.data.api.Write.newItem().
+ // args:
+ // A new item arguments object
+ // returns:
+ // A new item
+ return this.store.newItem(args); //Object
+ },
+
+ deleteItem: function(/*Object*/item){
+ // summary:
+ // Call deleteItem() method of a data store
+ // description:
+ // See dojo.data.api.Write.deleteItem().
+ // returns:
+ // A boolean
+ return this.store.deleteItem(item); //Boolean
+ },
+
+ revert: function(){
+ // summary:
+ // Call revert() method of a data store
+ // description:
+ // See dojo.data.api.Write.revert().
+ // returns:
+ // A boolean
+ return this.store.revert(); //Boolean
+ }
+});
+
+}
diff --git a/includes/js/dojox/wire/ml/Invocation.js b/includes/js/dojox/wire/ml/Invocation.js
new file mode 100644
index 0000000..3d36623
--- /dev/null
+++ b/includes/js/dojox/wire/ml/Invocation.js
@@ -0,0 +1,171 @@
+if(!dojo._hasResource["dojox.wire.ml.Invocation"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.wire.ml.Invocation"] = true;
+dojo.provide("dojox.wire.ml.Invocation");
+
+dojo.require("dojox.wire.ml.Action");
+
+dojo.declare("dojox.wire.ml.Invocation", dojox.wire.ml.Action, {
+ // summary:
+ // A widget to invoke a method or publish a topic
+ // description:
+ // This widget represents a controller task to invoke a method or
+ // publish a topic when an event (a function) or a topic is issued.
+ // object:
+ // A scope of a method to invoke
+ // method:
+ // A name of a method to invoke
+ // topic:
+ // A name of a topic to publish
+ // parameters:
+ // Arguments for the method or the topic
+ // result:
+ // A property to store a return value of the method call
+ // error:
+ // A property to store an error on the method call
+ object: "",
+ method: "",
+ topic: "",
+ parameters: "",
+ result: "",
+ error: "",
+
+ _run: function(){
+ // summary:
+ // Invoke a method or publish a topic
+ // description:
+ // If 'topic' is specified, the topic is published with arguments
+ // specified to 'parameters'.
+ // If 'method' and 'object' are specified, the method is invoked
+ // with arguments specified to 'parameters' and set the return
+ // value to a property specified to 'result'.
+ // 'object', 'parameters' and 'result' can specify properties of
+ // a widget or an DOM element with the dotted notation.
+ // If 'parameters' are omitted, the arguments to this method are
+ // passed as is.
+ if(this.topic){
+ var args = this._getParameters(arguments);
+ try{
+ dojo.publish(this.topic, args);
+ this.onComplete();
+ }catch(e){
+ this.onError(e);
+ }
+ }else if(this.method){
+ var scope = (this.object ? dojox.wire.ml._getValue(this.object) : dojo.global);
+ if(!scope){
+ return; //undefined
+ }
+ var args = this._getParameters(arguments);
+ var func = scope[this.method];
+ if(!func){
+ func = scope.callMethod;
+ if(!func){
+ return; //undefined
+ }
+ args = [this.method, args];
+ }
+ try{
+ var connected = false;
+ if(scope.getFeatures){
+ var features = scope.getFeatures();
+ if((this.method == "fetch" && features["dojo.data.api.Read"]) ||
+ (this.method == "save" && features["dojo.data.api.Write"])){
+ var arg = args[0];
+ if(!arg.onComplete){
+ arg.onComplete = function(){};
+ }
+ //dojo.connect(arg, "onComplete", this, "onComplete");
+ this.connect(arg, "onComplete", "onComplete");
+ if(!arg.onError){
+ arg.onError = function(){};
+ }
+ //dojo.connect(arg, "onError", this, "onError");
+ this.connect(arg, "onError", "onError");
+ connected = true;
+ }
+ }
+ var r = func.apply(scope, args);
+ if(!connected){
+ if(r && (r instanceof dojo.Deferred)){
+ var self = this;
+ r.addCallbacks(
+ function(result){self.onComplete(result);},
+ function(error){self.onError(error);}
+ );
+ }else{
+ this.onComplete(r);
+ }
+ }
+ }catch(e){
+ this.onError(e);
+ }
+ }
+ },
+
+ onComplete: function(/*anything*/result){
+ // summary:
+ // A function called when the method or the topic publish
+ // completed
+ // description:
+ // If 'result' attribute is specified, the result object also set
+ // to the specified property.
+ // result:
+ // The return value of a method or undefined for a topic
+ if(this.result){
+ dojox.wire.ml._setValue(this.result, result);
+ }
+ if(this.error){ // clear error
+ dojox.wire.ml._setValue(this.error, "");
+ }
+ },
+
+ onError: function(/*anything*/error){
+ // summary:
+ // A function called on an error occurs
+ // description:
+ // If 'error' attribute is specified, the error object also set to
+ // the specified property.
+ // error:
+ // The exception or error occurred
+ if(this.error){
+ if(error && error.message){
+ error = error.message;
+ }
+ dojox.wire.ml._setValue(this.error, error);
+ }
+ },
+
+ _getParameters: function(/*Array*/args){
+ // summary:
+ // Returns arguments to a method or topic to invoke
+ // description:
+ // This method retunrs an array of arguments specified by
+ // 'parameters' attribute, a comma-separated list of IDs and
+ // their properties in a dotted notation.
+ // If 'parameters' are omitted, the original arguments are
+ // used.
+ // args:
+ // Arguments to a trigger event or topic
+ if(!this.parameters){
+ // use arguments as is
+ return args; //Array
+ }
+ var parameters = [];
+ var list = this.parameters.split(",");
+ if(list.length == 1){
+ var parameter = dojox.wire.ml._getValue(dojo.trim(list[0]), args);
+ if(dojo.isArray(parameter)){
+ parameters = parameter;
+ }else{
+ parameters.push(parameter);
+ }
+ }else{
+ for(var i in list){
+ parameters.push(dojox.wire.ml._getValue(dojo.trim(list[i]), args));
+ }
+ }
+ return parameters; //Array
+ }
+});
+
+}
diff --git a/includes/js/dojox/wire/ml/Service.js b/includes/js/dojox/wire/ml/Service.js
new file mode 100644
index 0000000..15f074b
--- /dev/null
+++ b/includes/js/dojox/wire/ml/Service.js
@@ -0,0 +1,340 @@
+if(!dojo._hasResource["dojox.wire.ml.Service"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.wire.ml.Service"] = true;
+dojo.provide("dojox.wire.ml.Service");
+dojo.provide("dojox.wire.ml.RestHandler");
+dojo.provide("dojox.wire.ml.XmlHandler");
+dojo.provide("dojox.wire.ml.JsonHandler");
+
+dojo.require("dijit._Widget");
+dojo.require("dojox.data.dom");
+dojo.require("dojox.wire._base");
+dojo.require("dojox.wire.ml.util");
+
+dojo.declare("dojox.wire.ml.Service", dijit._Widget, {
+ // summary:
+ // A widget for a service
+ // description:
+ // This widget represents a service defined by a service description
+ // specified with 'url' attribute.
+ // If 'serviceType' and 'serviceUrl' attributes are specified, 'url'
+ // attribute can be omitted.
+ // url:
+ // A URL to a service description
+ // serviceUrl:
+ // A URL to a service
+ // serviceType:
+ // A service type
+ // handlerClass:
+ // A service handler class name
+ url: "",
+ serviceUrl: "",
+ serviceType: "",
+ handlerClass: "",
+ preventCache: true,
+
+ postCreate: function(){
+ // summary:
+ // Call _createHandler()
+ // description:
+ // See _createHandler().
+ this.handler = this._createHandler();
+ },
+
+ _handlerClasses: {
+ "TEXT": "dojox.wire.ml.RestHandler",
+ "XML": "dojox.wire.ml.XmlHandler",
+ "JSON": "dojox.wire.ml.JsonHandler",
+ "JSON-RPC": "dojo.rpc.JsonService"
+ },
+
+ _createHandler: function(){
+ // summary:
+ // Create a service handler
+ // desription:
+ // A service handler class is determined by:
+ // 1. 'handlerClass' attribute
+ // 2. 'serviceType' attribute
+ // 3. 'serviceType' property in a service description
+ // returns:
+ // A service handler
+ if(this.url){
+ var self = this;
+ var d = dojo.xhrGet({
+ url: this.url,
+ handleAs: "json",
+ sync: true
+ });
+ d.addCallback(function(result){
+ self.smd = result;
+ });
+ if(this.smd && !this.serviceUrl){
+ this.serviceUrl = (this.smd.serviceUrl || this.smd.serviceURL);
+ }
+ }
+ var handlerClass = undefined;
+ if(this.handlerClass){
+ handlerClass = dojox.wire._getClass(this.handlerClass);
+ }else if(this.serviceType){
+ handlerClass = this._handlerClasses[this.serviceType];
+ if(handlerClass && dojo.isString(handlerClass)){
+ handlerClass = dojox.wire._getClass(handlerClass);
+ this._handlerClasses[this.serviceType] = handlerClass;
+ }
+ }else if(this.smd && this.smd.serviceType){
+ handlerClass = this._handlerClasses[this.smd.serviceType];
+ if(handlerClass && dojo.isString(handlerClass)){
+ handlerClass = dojox.wire._getClass(handlerClass);
+ this._handlerClasses[this.smd.serviceType] = handlerClass;
+ }
+ }
+ if(!handlerClass){
+ return null; //null
+ }
+ return new handlerClass(); //Object
+ },
+
+ callMethod: function(method, parameters){
+ // summary:
+ // Call a service method with parameters
+ // method:
+ // A method name
+ // parameters:
+ // An array parameters
+ var deferred = new dojo.Deferred();
+ this.handler.bind(method, parameters, deferred, this.serviceUrl);
+ return deferred;
+ }
+});
+
+dojo.declare("dojox.wire.ml.RestHandler", null, {
+ // summary:
+ // A REST service handler
+ // description:
+ // This class serves as a base REST service.
+ // Sub-classes may override _getContent() and _getResult() to handle
+ // specific content types.
+ contentType: "text/plain",
+ handleAs: "text",
+
+ bind: function(method, parameters, deferred, url){
+ // summary:
+ // Call a service method with parameters.
+ // description:
+ // A service is called with a URL generated by _getUrl() and
+ // an HTTP method specified with 'method'.
+ // For "POST" and "PUT", a content is generated by _getContent().
+ // When data is loaded, _getResult() is used to pass the result to
+ // Deferred.callback().
+ // method:
+ // A method name
+ // parameters:
+ // An array of parameters
+ // deferred:
+ // 'Deferred'
+ // url:
+ // A URL for the method
+ method = method.toUpperCase();
+ var self = this;
+ var args = {
+ url: this._getUrl(method, parameters, url),
+ contentType: this.contentType,
+ handleAs: this.handleAs,
+ headers: this.headers,
+ preventCache: this.preventCache
+ };
+ var d = null;
+ if(method == "POST"){
+ args.postData = this._getContent(method, parameters);
+ d = dojo.rawXhrPost(args);
+ }else if(method == "PUT"){
+ args.putData = this._getContent(method, parameters);
+ d = dojo.rawXhrPut(args);
+ }else if(method == "DELETE"){
+ d = dojo.xhrDelete(args);
+ }else{ // "GET"
+ d = dojo.xhrGet(args);
+ }
+ d.addCallbacks(function(result){
+ deferred.callback(self._getResult(result));
+ }, function(error){
+ deferred.errback(error);
+ });
+ },
+
+ _getUrl: function(/*String*/method, /*Array*/parameters, /*String*/url){
+ // summary:
+ // Generate a URL
+ // description:
+ // If 'method' is "GET" or "DELETE", a query string is generated
+ // from a query object specified to the first parameter in
+ // 'parameters' and appended to 'url'.
+ // If 'url' contains variable seguments ("{parameter_name}"),
+ // they are replaced with corresponding parameter values, instead.
+ // method:
+ // A method name
+ // parameters:
+ // An array of parameters
+ // url:
+ // A base URL
+ // returns:
+ // A URL
+ var query;
+ if(method == "GET" || method == "DELETE"){
+ if(parameters.length > 0){
+ query = parameters[0];
+ }
+ }else{ // "POST" || "PUT"
+ if(parameters.length > 1){
+ query = parameters[1];
+ }
+ }
+ if(query){
+ var queryString = "";
+ for(var name in query){
+ var value = query[name];
+ if(value){
+ value = encodeURIComponent(value);
+ var variable = "{" + name + "}";
+ var index = url.indexOf(variable);
+ if(index >= 0){ // encode in path
+ url = url.substring(0, index) + value + url.substring(index + variable.length);
+ }else{ // encode as query string
+ if(queryString){
+ queryString += "&";
+ }
+ queryString += (name + "=" + value);
+ }
+ }
+ }
+ if(queryString){
+ url += "?" + queryString;
+ }
+ }
+ return url; //String
+ },
+
+ _getContent: function(/*String*/method, /*Array*/parameters){
+ // summary:
+ // Generate a request content
+ // description:
+ // If 'method' is "POST" or "PUT", the first parameter in
+ // 'parameters' is returned.
+ // method:
+ // A method name
+ // parameters:
+ // An array of parameters
+ // returns:
+ // A request content
+ if(method == "POST" || method == "PUT"){
+ return (parameters ? parameters[0] : null); //anything
+ }else{
+ return null; //null
+ }
+ },
+
+ _getResult: function(/*anything*/data){
+ // summary:
+ // Extract a result
+ // description:
+ // A response data is returned as is.
+ // data:
+ // A response data returned by a service
+ // returns:
+ // A result object
+ return data; //anything
+ }
+});
+
+dojo.declare("dojox.wire.ml.XmlHandler", dojox.wire.ml.RestHandler, {
+ // summary:
+ // A REST service handler for XML
+ // description:
+ // This class provides XML handling for a REST service.
+ contentType: "text/xml",
+ handleAs: "xml",
+
+ _getContent: function(/*String*/method, /*Array*/parameters){
+ // description:
+ // If 'method' is "POST" or "PUT", the first parameter in
+ // 'parameters' is used to generate an XML content.
+ // method:
+ // A method name
+ // parameters:
+ // An array of parameters
+ // returns:
+ // A request content
+ var content = null;
+ if(method == "POST" || method == "PUT"){
+ var p = parameters[0];
+ if(p){
+ if(dojo.isString(p)){
+ content = p;
+ }else{
+ var element = p;
+ if(element instanceof dojox.wire.ml.XmlElement){
+ element = element.element;
+ }else if(element.nodeType === 9 /* DOCUMENT_NODE */){
+ element = element.documentElement;
+ }
+ var declaration = "<?xml version=\"1.0\"?>"; // TODO: encoding?
+ content = declaration + dojox.data.dom.innerXML(element);
+ }
+ }
+ }
+ return content;
+ },
+
+ _getResult: function(/*Document*/data){
+ // summary:
+ // Extract a result
+ // description:
+ // A response data (XML Document) is returned wrapped with
+ // XmlElement.
+ // data:
+ // A response data returned by a service
+ // returns:
+ // A result object
+ if(data){
+ data = new dojox.wire.ml.XmlElement(data);
+ }
+ return data;
+ }
+});
+
+dojo.declare("dojox.wire.ml.JsonHandler", dojox.wire.ml.RestHandler, {
+ // summary:
+ // A REST service handler for JSON
+ // description:
+ // This class provides JSON handling for a REST service.
+ contentType: "text/json",
+ handleAs: "json",
+ headers: {"Accept": "*/json"},
+
+ _getContent: function(/*String*/method, /*Array*/parameters){
+ // summary:
+ // Generate a request content
+ // description:
+ // If 'method' is "POST" or "PUT", the first parameter in
+ // 'parameter' is used to generate a JSON content.
+ // method:
+ // A method name
+ // parameters:
+ // An array of parameters
+ // returns:
+ // A request content
+ var content = null;
+ if(method == "POST" || method == "PUT"){
+ var p = (parameters ? parameters[0] : undefined);
+ if(p){
+ if(dojo.isString(p)){
+ content = p;
+ }else{
+ content = dojo.toJson(p);
+ }
+ }
+ }
+ return content; //String
+ }
+});
+
+}
diff --git a/includes/js/dojox/wire/ml/Transfer.js b/includes/js/dojox/wire/ml/Transfer.js
new file mode 100644
index 0000000..c7780ca
--- /dev/null
+++ b/includes/js/dojox/wire/ml/Transfer.js
@@ -0,0 +1,359 @@
+if(!dojo._hasResource["dojox.wire.ml.Transfer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.wire.ml.Transfer"] = true;
+dojo.provide("dojox.wire.ml.Transfer");
+dojo.provide("dojox.wire.ml.ChildWire");
+dojo.provide("dojox.wire.ml.ColumnWire");
+dojo.provide("dojox.wire.ml.NodeWire");
+dojo.provide("dojox.wire.ml.SegmentWire");
+
+dojo.require("dijit._Widget");
+dojo.require("dijit._Container");
+dojo.require("dojox.wire._base");
+dojo.require("dojox.wire.ml.Action");
+
+dojo.declare("dojox.wire.ml.Transfer", dojox.wire.ml.Action, {
+ // summary:
+ // A widget to transfer values through source and target Wires
+ // description:
+ // This widget represents a controller task to transfer a value from
+ // a source to a target, through a source and a target Wires, when
+ // an event (a function) or a topic is issued.
+ // If this widget has child ChildWire widgets, their _addWire()
+ // methods are called to add Wire arguments to a source or a target
+ // Wire.
+ // source:
+ // A source object and/or property
+ // sourceStore:
+ // A data store for a source data item
+ // sourceAttribute:
+ // An attribute of a source data item
+ // sourcePath:
+ // A simplified XPath to a source property of an XML element
+ // type:
+ // A type of the value to be transferred
+ // converter:
+ // A class name of a converter for the value to be transferred
+ // target:
+ // A target object and/or property
+ // targetStore:
+ // A data store for a target data item
+ // targetAttribute:
+ // An attribute of a target data item
+ // targetPath:
+ // A simplified XPath to a target property of an XML element
+ source: "",
+ sourceStore: "",
+ sourceAttribute: "",
+ sourcePath: "",
+ type: "",
+ converter: "",
+ delimiter: "",
+ target: "",
+ targetStore: "",
+ targetAttribute: "",
+ targetPath: "",
+
+ _run: function(){
+ // summary:
+ // Transfer a value from a source to a target
+ // description:
+ // First, Wires for a source and a target are created from attributes.
+ // Then, a value is obtained by getValue() of the source Wire is set
+ // by setValue() of the target Wire.
+ // The arguments to this method is passed to getValue() and setValue()
+ // of Wires, so that they can be used to identify the root objects off
+ // the arguments.
+ var sourceWire = this._getWire("source");
+ var targetWire = this._getWire("target");
+ dojox.wire.transfer(sourceWire, targetWire, arguments);
+ },
+
+ _getWire: function(/*String*/which){
+ // summary:
+ // Build Wire arguments from attributes
+ // description:
+ // Arguments object for a source or a target Wire, specified by
+ // 'which' argument, are build from corresponding attributes,
+ // including '*Store' (for 'dataStore'), '*Attribute'
+ // (for 'attribute), '*Path' (for 'path'), 'type' and 'converter'.
+ // 'source' or 'target' attribute is parsed as:
+ // "object_id.property_name[.sub_property_name...]"
+ // If 'source' or 'target' starts with "arguments", 'object'
+ // argument for a Wire is set to null, so that the root object is
+ // given as an event or topic arguments.
+ // If this widget has child ChildWire widgets with a corresponding
+ // 'which' attribute, their _addWire() methods are called to add
+ // additional Wire arguments and nested Wire is created,
+ // specifying the Wire defined by this widget to 'object' argument.
+ // which:
+ // Which Wire arguments to build, "source" or "target"
+ // returns:
+ // Wire arguments object
+ var args = undefined;
+ if(which == "source"){
+ args = {
+ object: this.source,
+ dataStore: this.sourceStore,
+ attribute: this.sourceAttribute,
+ path: this.sourcePath,
+ type: this.type,
+ converter: this.converter
+ };
+ }else{ // "target"
+ args = {
+ object: this.target,
+ dataStore: this.targetStore,
+ attribute: this.targetAttribute,
+ path: this.targetPath
+ };
+ }
+ if(args.object){
+ if(args.object.length >= 9 && args.object.substring(0, 9) == "arguments"){
+ args.property = args.object.substring(9);
+ args.object = null;
+ }else{
+ var i = args.object.indexOf('.');
+ if(i < 0){
+ args.object = dojox.wire.ml._getValue(args.object);
+ }else{
+ args.property = args.object.substring(i + 1);
+ args.object = dojox.wire.ml._getValue(args.object.substring(0, i));
+ }
+ }
+ }
+ if(args.dataStore){
+ args.dataStore = dojox.wire.ml._getValue(args.dataStore);
+ }
+ var childArgs = undefined;
+ var children = this.getChildren();
+ for(var i in children){
+ var child = children[i];
+ if(child instanceof dojox.wire.ml.ChildWire && child.which == which){
+ if(!childArgs){
+ childArgs = {};
+ }
+ child._addWire(this, childArgs);
+ }
+ }
+ if(childArgs){ // make nested Wires
+ childArgs.object = dojox.wire.create(args);
+ childArgs.dataStore = args.dataStore;
+ args = childArgs;
+ }
+ return args; //Object
+ }
+});
+
+dojo.declare("dojox.wire.ml.ChildWire", dijit._Widget, {
+ // summary:
+ // A widget to add a child wire
+ // description:
+ // Attributes of this widget are used to add a child Wire to
+ // a composite Wire of the parent Transfer widget.
+ // which:
+ // Which Wire to add a child Wire, "source" or "target", default to
+ // "source"
+ // object:
+ // A root object for the value
+ // property:
+ // A property for the value
+ // type:
+ // A type of the value
+ // converter:
+ // A class name of a converter for the value
+ // attribute:
+ // A data item attribute for the value
+ // path:
+ // A simplified XPath for the value
+ // name:
+ // A composite property name
+ which: "source",
+ object: "",
+ property: "",
+ type: "",
+ converter: "",
+ attribute: "",
+ path: "",
+ name: "",
+
+ _addWire: function(/*Transfer*/parent, /*Object*/args){
+ // summary:
+ // Add a child Wire to Wire arguments
+ // description:
+ // If 'name' attribute is specified, a child Wire is added as
+ // the named property of 'children' object of 'args'.
+ // Otherwise, a child Wire is added to 'children' array of 'args'.
+ // parent:
+ // A parent Transfer widget
+ // args:
+ // Wire arguments
+ if(this.name){ // object
+ if(!args.children){
+ args.children = {};
+ }
+ args.children[this.name] = this._getWire(parent);
+ }else{ // array
+ if(!args.children){
+ args.children = [];
+ }
+ args.children.push(this._getWire(parent));
+ }
+ },
+
+ _getWire: function(/*Transfer*/parent){
+ // summary:
+ // Build child Wire arguments from attributes
+ // description:
+ // Arguments object for a child Wire are build from attributes,
+ // including 'object', 'property', 'type', 'converter',
+ // 'attribute' and 'path'.
+ // parent:
+ // A parent Transfer widget
+ // returns:
+ // Wire arguments object
+ return {
+ object: (this.object ? dojox.wire.ml._getValue(this.object) : undefined),
+ property: this.property,
+ type: this.type,
+ converter: this.converter,
+ attribute: this.attribute,
+ path: this.path
+ }; //Object
+ }
+});
+
+dojo.declare("dojox.wire.ml.ColumnWire", dojox.wire.ml.ChildWire, {
+ // summary:
+ // A widget to add a column wire
+ // description:
+ // Attributes of this widget are used to add a column Wire to
+ // a TableAdapter of the parent Transfer widget.
+ // column:
+ // A column name
+ column: "",
+
+ _addWire: function(/*Transfer*/parent, /*Object*/args){
+ // summary:
+ // Add a column Wire to Wire arguments
+ // description:
+ // If 'column' attribute is specified, a column Wire is added as
+ // the named property of 'columns' object of 'args'.
+ // Otherwise, a column Wire is added to 'columns' array of 'args'.
+ // parent:
+ // A parent Transfer widget
+ // args:
+ // Wire arguments
+ if(this.column){ // object
+ if(!args.columns){
+ args.columns = {};
+ }
+ args.columns[this.column] = this._getWire(parent);
+ }else{ // array
+ if(!args.columns){
+ args.columns = [];
+ }
+ args.columns.push(this._getWire(parent));
+ }
+ }
+});
+
+dojo.declare("dojox.wire.ml.NodeWire", [dojox.wire.ml.ChildWire, dijit._Container], {
+ // summary:
+ // A widget to add node wires
+ // description:
+ // Attributes of this widget are used to add node Wires to
+ // a TreeAdapter of the parent Transfer widget.
+ // titleProperty:
+ // A property for the node title
+ // titleAttribute:
+ // A data item attribute for the node title
+ // titlePath:
+ // A simplified XPath for the node title
+ titleProperty: "",
+ titleAttribute: "",
+ titlePath: "",
+
+ _addWire: function(/*Transfer*/parent, /*Object*/args){
+ // summary:
+ // Add node Wires to Wire arguments
+ // description:
+ // Node Wires are added to 'nodes' array of 'args'.
+ // parent:
+ // A parent Transfer widget
+ // args:
+ // Wire arguments
+ if(!args.nodes){
+ args.nodes = [];
+ }
+ args.nodes.push(this._getWires(parent));
+ },
+
+ _getWires: function(/*Transfer*/parent){
+ // summary:
+ // Build node Wires arguments from attributes
+ // description:
+ // Arguments object for 'node' Wire are build from attributes,
+ // including 'object', 'property', 'type', 'converter',
+ // 'attribute' and 'path'.
+ // Arguments object for 'title' Wire are build from another set of
+ // attributes, 'titleProperty', 'titleAttribute' and 'titlePath'.
+ // If this widget has child NodeWire widgets, their _getWires()
+ // methods are called recursively to build 'children' array of
+ // 'args'.
+ // parent:
+ // A parent Transfer widget
+ // returns:
+ // Wire arguments object
+ var args = {
+ node: this._getWire(parent),
+ title: {
+ type: "string",
+ property: this.titleProperty,
+ attribute: this.titleAttribute,
+ path: this.titlePath
+ }
+ };
+ var childArgs = [];
+ var children = this.getChildren();
+ for(var i in children){
+ var child = children[i];
+ if(child instanceof dojox.wire.ml.NodeWire){
+ childArgs.push(child._getWires(parent));
+ }
+ }
+ if(childArgs.length > 0){
+ args.children = childArgs;
+ }
+ return args; //Object
+ }
+});
+
+dojo.declare("dojox.wire.ml.SegmentWire", dojox.wire.ml.ChildWire, {
+ // summary:
+ // A widget to add a segment wire
+ // description:
+ // Attributes of this widget are used to add a segment Wire to
+ // a TextAdapter of the parent Transfer widget.
+
+ _addWire: function(/*Transfer*/parent, /*Object*/args){
+ // summary:
+ // Add a segument Wire to Wire arguments
+ // description:
+ // A segment Wire is added to 'segments' array of 'args'.
+ // If 'parent' has 'delimiter' attribute, it is used for
+ // 'delimiter' property of 'args'.
+ // parent:
+ // A parent Transfer widget
+ // args:
+ // Wire arguments
+ if(!args.segments){
+ args.segments = [];
+ }
+ args.segments.push(this._getWire(parent));
+ if(parent.delimiter && !args.delimiter){
+ args.delimiter = parent.delimiter;
+ }
+ }
+});
+
+}
diff --git a/includes/js/dojox/wire/ml/util.js b/includes/js/dojox/wire/ml/util.js
new file mode 100644
index 0000000..a336b28
--- /dev/null
+++ b/includes/js/dojox/wire/ml/util.js
@@ -0,0 +1,295 @@
+if(!dojo._hasResource["dojox.wire.ml.util"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.wire.ml.util"] = true;
+dojo.provide("dojox.wire.ml.util");
+
+dojo.require("dojox.data.dom");
+dojo.require("dojox.wire.Wire");
+
+dojox.wire.ml._getValue = function(/*String*/source, /*Array*/args){
+ // summary:
+ // Return a value
+ // description:
+ // This method obtains an object by an ID of a widget or an DOM
+ // element.
+ // If 'source' specifies a dotted notation to its property, a Wire is
+ // used to get the object property.
+ // If 'source' starts with "arguments", 'args' is used as a root
+ // object for the Wire.
+ // source:
+ // A string to specify an object and its property
+ // args:
+ // An optional arguments array
+ // returns:
+ // A value
+ if(!source){
+ return undefined; //undefined
+ }
+ var property = undefined;
+ if(args && source.length >= 9 && source.substring(0, 9) == "arguments"){
+ property = source.substring(9);
+ return new dojox.wire.Wire({property: property}).getValue(args);
+ }
+ var i = source.indexOf('.');
+ if(i >= 0){
+ property = source.substring(i + 1);
+ source = source.substring(0, i);
+ }
+ var object = (dijit.byId(source) || dojo.byId(source) || dojo.getObject(source));
+ if(!object){
+ return undefined; //undefined
+ }
+ if(!property){
+ return object; //Object
+ }else{
+ return new dojox.wire.Wire({object: object, property: property}).getValue(); //anything
+ }
+};
+
+dojox.wire.ml._setValue = function(/*String*/target, /*anything*/value){
+ // summary:
+ // Store a value
+ // description:
+ // This method stores a value by an ID of a widget or an DOM
+ // element with a dotted notation to its property, using a Wire.
+ // target:
+ // A string to specify an object and its property
+ // value:
+ // A value
+ if(!target){
+ return; //undefined
+ }
+ var i = target.indexOf('.');
+ if(i < 0){
+ return; //undefined
+ }
+ var object = this._getValue(target.substring(0, i));
+ if(!object){
+ return; //undefined
+ }
+ var property = target.substring(i + 1);
+ new dojox.wire.Wire({object: object, property: property}).setValue(value);
+};
+
+dojo.declare("dojox.wire.ml.XmlElement", null, {
+ // summary:
+ // An object wrapping an XML element
+ // description:
+ // This class represents an XML element.
+
+ constructor: function(/*Element||String*/element){
+ // summary:
+ // Initialize with an XML element or a tag name
+ // element:
+ // An XML element or a tag name
+ if(dojo.isString(element)){
+ element = this._getDocument().createElement(element);
+ }
+ this.element = element;
+ },
+ getPropertyValue: function(/*String*/property){
+ // summary:
+ // Return a property value
+ // description:
+ // If 'property' starts with '@', the attribute value is returned.
+ // If 'property' specifies "text()", the value of the first child
+ // text is returned.
+ // Otherwise, child elements of the tag name specified with
+ // 'property' are returned.
+ // property:
+ // A property name
+ // returns:
+ // A property value
+ var value = undefined;
+ if(!this.element){
+ return value; //undefined
+ }
+ if(!property){
+ return value; //undefined
+ }
+
+ if(property.charAt(0) == '@'){
+ var attribute = property.substring(1);
+ value = this.element.getAttribute(attribute);
+ }else if(property == "text()"){
+ var text = this.element.firstChild;
+ if(text){
+ value = text.nodeValue;
+ }
+ }else{ // child elements
+ var elements = [];
+ for(var i = 0; i < this.element.childNodes.length; i++){
+ var child = this.element.childNodes[i];
+ if(child.nodeType === 1 /* ELEMENT_NODE */ && child.nodeName == property){
+ elements.push(new dojox.wire.ml.XmlElement(child));
+ }
+ }
+ if(elements.length > 0){
+ if(elements.length === 1){
+ value = elements[0];
+ }else{
+ value = elements;
+ }
+ }
+ }
+ return value; //String||Array||XmlElement
+ },
+
+ setPropertyValue: function(/*String*/property, /*String||Array||XmlElement*/value){
+ // summary:
+ // Store a property value
+ // description:
+ // If 'property' starts with '@', 'value' is set to the attribute.
+ // If 'property' specifies "text()", 'value' is set as the first
+ // child text.
+ // If 'value' is a string, a child element of the tag name
+ // specified with 'property' is created and 'value' is set as
+ // the first child text of the child element.
+ // Otherwise, 'value' is set to as child elements.
+ // property:
+ // A property name
+ // value:
+ // A property value
+ if(!this.element){
+ return; //undefined
+ }
+ if(!property){
+ return; //undefined
+ }
+
+ if(property.charAt(0) == '@'){
+ var attribute = property.substring(1);
+ if(value){
+ this.element.setAttribute(attribute, value);
+ }else{
+ this.element.removeAttribute(attribute);
+ }
+ }else if(property == "text()"){
+ while(this.element.firstChild){
+ this.element.removeChild(this.element.firstChild);
+ }
+ if(value){
+ var text = this._getDocument().createTextNode(value);
+ this.element.appendChild(text);
+ }
+ }else{ // child elements
+ var nextChild = null;
+ for(var i = this.element.childNodes.length - 1; i >= 0; i--){
+ var child = this.element.childNodes[i];
+ if(child.nodeType === 1 /* ELEMENT_NODE */ && child.nodeName == property){
+ if(!nextChild){
+ nextChild = child.nextSibling;
+ }
+ this.element.removeChild(child);
+ }
+ }
+ if(value){
+ if(dojo.isArray(value)){
+ for(var i in value){
+ var e = value[i];
+ if(e.element){
+ this.element.insertBefore(e.element, nextChild);
+ }
+ }
+ }else if(value instanceof dojox.wire.ml.XmlElement){
+ if(value.element){
+ this.element.insertBefore(value.element, nextChild);
+ }
+ }else{ // assume string
+ var child = this._getDocument().createElement(property);
+ var text = this._getDocument().createTextNode(value);
+ child.appendChild(text);
+ this.element.insertBefore(child, nextChild);
+ }
+ }
+ }
+ },
+
+ toString: function(){
+ // summary:
+ // Return a value of the first text child of the element
+ // description:
+ // A value of the first text child of the element is returned.
+ // returns:
+ // A value of the first text child of the element
+ var s = "";
+ if(this.element){
+ var text = this.element.firstChild;
+ if(text){
+ s = text.nodeValue;
+ }
+ }
+ return s; //String
+ },
+
+ toObject: function(){
+ // summary:
+ // Return an object representation of the element
+ // description:
+ // An object with properties for child elements, attributes and
+ // text is returned.
+ // returns:
+ // An object representation of the element
+ if(!this.element){
+ return null; //null
+ }
+ var text = "";
+ var obj = {};
+ var elements = 0;
+ for(var i = 0; i < this.element.childNodes.length; i++){
+ var child = this.element.childNodes[i];
+ if(child.nodeType === 1 /* ELEMENT_NODE */){
+ elements++;
+ var o = new dojox.wire.ml.XmlElement(child).toObject();
+ var name = child.nodeName;
+ var p = obj[name];
+ if(!p){
+ obj[name] = o;
+ }else if(dojo.isArray(p)){
+ p.push(o);
+ }else{
+ obj[name] = [p, o]; // make them array
+ }
+ }else if(child.nodeType === 3 /* TEXT_NODE */ ||
+ child.nodeType === 4 /* CDATA_SECTION_NODE */){
+ text += child.nodeValue;
+ }
+ }
+ var attributes = 0;
+ if(this.element.nodeType === 1 /* ELEMENT_NODE */){
+ attributes = this.element.attributes.length;
+ for(var i = 0; i < attributes; i++){
+ var attr = this.element.attributes[i];
+ obj["@" + attr.nodeName] = attr.nodeValue;
+ }
+ }
+ if(elements === 0){
+ if(attributes === 0){
+ // text only
+ return text; //String
+ }
+ // text with attributes
+ obj["text()"] = text;
+ }
+ // else ignore text
+ return obj; //Object
+ },
+
+ _getDocument: function(){
+ // summary:
+ // Return a DOM document
+ // description:
+ // If 'element' is specified, a DOM document of the element is
+ // returned.
+ // Otherwise, a DOM document is created.
+ // returns:
+ // A DOM document
+ if(this.element){
+ return (this.element.nodeType == 9 /* DOCUMENT_NODE */ ?
+ this.element : this.element.ownerDocument); //Document
+ }else{
+ return dojox.data.dom.createDocument(); //Document
+ }
+ }
+});
+
+}
diff --git a/includes/js/dojox/wire/tests/markup/Action.html b/includes/js/dojox/wire/tests/markup/Action.html
new file mode 100644
index 0000000..75cbd49
--- /dev/null
+++ b/includes/js/dojox/wire/tests/markup/Action.html
@@ -0,0 +1,147 @@
+<html>
+<head>
+<title>Test Action</title>
+<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+<script type="text/javascript">
+dojo.provide("dojox.wire.ml.tests.markup.Action");
+
+dojo.require("dojo.parser");
+dojo.require("doh.runner");
+dojo.require("dojox.wire.ml.Action");
+dojo.require("dojox.wire.ml.Transfer");
+
+dojox.wire.ml.tests.markup.Action = {
+ transfer: function(){},
+ source: {a: "A", b: "B"}
+};
+
+dojo.addOnLoad(function(){
+ doh.register("dojox.wire.ml.tests.markup.Action", [
+ function test_Action_triggerEvent(t){
+ dojox.wire.ml.tests.markup.Action.target = {};
+ dojox.wire.ml.tests.markup.Action.transfer();
+ t.assertEqual(dojox.wire.ml.tests.markup.Action.source.a, dojox.wire.ml.tests.markup.Action.target.a);
+ t.assertEqual(dojox.wire.ml.tests.markup.Action.source.b, dojox.wire.ml.tests.markup.Action.target.b);
+ },
+
+ function test_Action_triggerTopic(t){
+ dojox.wire.ml.tests.markup.Action.target = {};
+ dojo.publish("transfer");
+ t.assertEqual(dojox.wire.ml.tests.markup.Action.source.a, dojox.wire.ml.tests.markup.Action.target.a);
+ },
+
+ function test_ActionFilter_required(t){
+ dojox.wire.ml.tests.markup.Action.target = {};
+ dojo.publish("transferFilter");
+ t.assertEqual(undefined, dojox.wire.ml.tests.markup.Action.target.a);
+ t.assertEqual("no required", dojox.wire.ml.tests.markup.Action.error);
+ dojox.wire.ml.tests.markup.Action.required = true;
+ dojo.publish("transferFilter");
+ t.assertEqual(dojox.wire.ml.tests.markup.Action.source.a, dojox.wire.ml.tests.markup.Action.target.a);
+ },
+
+ function test_ActionFilter_requiredSpecificNumber(t){
+ dojox.wire.ml.tests.markup.Action.value = null
+ dojox.wire.ml.tests.markup.Action.target = {};
+ dojo.publish("transferFilterNumber");
+
+ t.assertEqual(undefined, dojox.wire.ml.tests.markup.Action.target.a);
+
+ dojox.wire.ml.tests.markup.Action.value = 20;
+ dojo.publish("transferFilterNumber");
+ t.assertEqual(dojox.wire.ml.tests.markup.Action.source.a, dojox.wire.ml.tests.markup.Action.target.a);
+ },
+
+ function test_ActionFilter_requiredSpecificBoolean(t){
+ dojox.wire.ml.tests.markup.Action.value = null;
+ dojox.wire.ml.tests.markup.Action.target = {};
+ dojo.publish("transferFilterBoolean");
+
+ t.assertEqual(undefined, dojox.wire.ml.tests.markup.Action.target.a);
+
+ dojox.wire.ml.tests.markup.Action.value = true;
+ dojo.publish("transferFilterBoolean");
+ t.assertEqual(dojox.wire.ml.tests.markup.Action.source.a, dojox.wire.ml.tests.markup.Action.target.a);
+ },
+
+ function test_ActionFilter_requiredSpecificString(t){
+ dojox.wire.ml.tests.markup.Action.target = {};
+ dojox.wire.ml.tests.markup.Action.value = null;
+ dojo.publish("transferFilterString");
+
+ t.assertEqual(undefined, dojox.wire.ml.tests.markup.Action.target.a);
+
+ dojox.wire.ml.tests.markup.Action.value = "executeThis";
+ dojo.publish("transferFilterString");
+ t.assertEqual(dojox.wire.ml.tests.markup.Action.source.a, dojox.wire.ml.tests.markup.Action.target.a);
+ }
+ ]);
+ doh.run();
+});
+</script>
+</head>
+<body>
+<div dojoType="dojox.wire.ml.Action"
+ trigger="dojox.wire.ml.tests.markup.Action"
+ triggerEvent="transfer">
+ <div dojoType="dojox.wire.ml.Transfer"
+ source="dojox.wire.ml.tests.markup.Action.source.a"
+ target="dojox.wire.ml.tests.markup.Action.target.a"></div>
+ <div dojoType="dojox.wire.ml.Transfer"
+ source="dojox.wire.ml.tests.markup.Action.source.b"
+ target="dojox.wire.ml.tests.markup.Action.target.b"></div>
+</div>
+<div dojoType="dojox.wire.ml.Action"
+ triggerTopic="transfer">
+ <div dojoType="dojox.wire.ml.Transfer"
+ source="dojox.wire.ml.tests.markup.Action.source.a"
+ target="dojox.wire.ml.tests.markup.Action.target.a"></div>
+</div>
+<div dojoType="dojox.wire.ml.Action"
+ triggerTopic="transferFilter">
+ <div dojoType="dojox.wire.ml.ActionFilter"
+ required="dojox.wire.ml.tests.markup.Action.required"
+ message="no required"
+ error="dojox.wire.ml.tests.markup.Action.error"></div>
+ <div dojoType="dojox.wire.ml.Transfer"
+ source="dojox.wire.ml.tests.markup.Action.source.a"
+ target="dojox.wire.ml.tests.markup.Action.target.a"></div>
+</div>
+
+<div dojoType="dojox.wire.ml.Action"
+ triggerTopic="transferFilterNumber">
+ <div dojoType="dojox.wire.ml.ActionFilter"
+ required="dojox.wire.ml.tests.markup.Action.value"
+ requiredValue="20"
+ type="number">
+ </div>
+ <div dojoType="dojox.wire.ml.Transfer"
+ source="dojox.wire.ml.tests.markup.Action.source.a"
+ target="dojox.wire.ml.tests.markup.Action.target.a"></div>
+</div>
+
+<div dojoType="dojox.wire.ml.Action"
+ triggerTopic="transferFilterBoolean">
+ <div dojoType="dojox.wire.ml.ActionFilter"
+ required="dojox.wire.ml.tests.markup.Action.value"
+ requiredValue="true"
+ type="boolean">
+ </div>
+ <div dojoType="dojox.wire.ml.Transfer"
+ source="dojox.wire.ml.tests.markup.Action.source.a"
+ target="dojox.wire.ml.tests.markup.Action.target.a"></div>
+</div>
+
+<div dojoType="dojox.wire.ml.Action"
+ triggerTopic="transferFilterString">
+ <div dojoType="dojox.wire.ml.ActionFilter"
+ required="dojox.wire.ml.tests.markup.Action.value"
+ requiredValue="executeThis">
+ </div>
+ <div dojoType="dojox.wire.ml.Transfer"
+ source="dojox.wire.ml.tests.markup.Action.source.a"
+ target="dojox.wire.ml.tests.markup.Action.target.a"></div>
+</div>
+
+</body>
+</html>
diff --git a/includes/js/dojox/wire/tests/markup/Data.html b/includes/js/dojox/wire/tests/markup/Data.html
new file mode 100644
index 0000000..b1107c0
--- /dev/null
+++ b/includes/js/dojox/wire/tests/markup/Data.html
@@ -0,0 +1,105 @@
+<html>
+<head>
+<title>Test Data</title>
+<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+<script type="text/javascript">
+dojo.provide("dojox.wire.ml.tests.markup.Data");
+
+dojo.require("dojo.parser");
+dojo.require("doh.runner");
+dojo.require("dojox.wire.ml.Action");
+dojo.require("dojox.wire.ml.Data");
+dojo.require("dojox.wire.ml.Transfer");
+
+dojox.wire.ml.tests.markup.Data = {};
+
+dojo.addOnLoad(function(){
+ doh.register("dojox.wire.ml.tests.markup.Data", [
+
+ function test_DataProperty(t){
+ dojox.wire.ml.tests.markup.Data.target = {};
+ dojo.publish("transfer");
+ t.assertEqual("A", dojox.wire.ml.tests.markup.Data.target.a);
+ t.assertEqual(1, dojox.wire.ml.tests.markup.Data.target.b);
+ t.assertEqual(true, dojox.wire.ml.tests.markup.Data.target.c);
+ t.assertEqual("DA", dojox.wire.ml.tests.markup.Data.target.d.a);
+ t.assertEqual("DB", dojox.wire.ml.tests.markup.Data.target.d.b);
+ t.assertEqual("E1", dojox.wire.ml.tests.markup.Data.target.e[0]);
+ t.assertEqual("E2", dojox.wire.ml.tests.markup.Data.target.e[1]);
+ t.assertEqual("F", dojox.wire.ml.tests.markup.Data.target.f);
+ t.assertEqual("G", dojox.wire.ml.tests.markup.Data.target.g);
+ }
+
+ ]);
+ doh.run();
+});
+</script>
+</head>
+<body>
+<div dojoType="dojox.wire.ml.Data"
+ id="Data1">
+ <div dojoType="dojox.wire.ml.DataProperty"
+ name="a"
+ value="A"></div>
+ <div dojoType="dojox.wire.ml.DataProperty"
+ name="b"
+ type="number" value="1"></div>
+ <div dojoType="dojox.wire.ml.DataProperty"
+ name="c"
+ type="boolean" value="true"></div>
+ <div dojoType="dojox.wire.ml.DataProperty"
+ name="d"
+ type="object">
+ <div dojoType="dojox.wire.ml.DataProperty"
+ name="a"
+ value="DA"></div>
+ <div dojoType="dojox.wire.ml.DataProperty"
+ name="b"
+ value="DB"></div>
+ </div>
+ <div dojoType="dojox.wire.ml.DataProperty"
+ name="e"
+ type="array">
+ <div dojoType="dojox.wire.ml.DataProperty"
+ value="E1"></div>
+ <div dojoType="dojox.wire.ml.DataProperty"
+ value="E2"></div>
+ </div>
+ <div dojoType="dojox.wire.ml.DataProperty"
+ name="f"
+ type="element"
+ value="x">
+ <div dojoType="dojox.wire.ml.DataProperty"
+ name="text()"
+ value="F"></div>
+ <div dojoType="dojox.wire.ml.DataProperty"
+ name="@y"
+ value="G"></div>
+ </div>
+</div>
+<div dojoType="dojox.wire.ml.Action"
+ triggerTopic="transfer">
+ <div dojoType="dojox.wire.ml.Transfer"
+ source="Data1.a"
+ target="dojox.wire.ml.tests.markup.Data.target.a"></div>
+ <div dojoType="dojox.wire.ml.Transfer"
+ source="Data1.b"
+ target="dojox.wire.ml.tests.markup.Data.target.b"></div>
+ <div dojoType="dojox.wire.ml.Transfer"
+ source="Data1.c"
+ target="dojox.wire.ml.tests.markup.Data.target.c"></div>
+ <div dojoType="dojox.wire.ml.Transfer"
+ source="Data1.d"
+ target="dojox.wire.ml.tests.markup.Data.target.d"></div>
+ <div dojoType="dojox.wire.ml.Transfer"
+ source="Data1.e"
+ target="dojox.wire.ml.tests.markup.Data.target.e"></div>
+ <div dojoType="dojox.wire.ml.Transfer"
+ source="Data1.f"
+ target="dojox.wire.ml.tests.markup.Data.target.f"></div>
+ <div dojoType="dojox.wire.ml.Transfer"
+ source="Data1.f.@y"
+ target="dojox.wire.ml.tests.markup.Data.target.g"></div>
+</div>
+</body>
+</html>
diff --git a/includes/js/dojox/wire/tests/markup/DataStore.html b/includes/js/dojox/wire/tests/markup/DataStore.html
new file mode 100644
index 0000000..3c55f7e
--- /dev/null
+++ b/includes/js/dojox/wire/tests/markup/DataStore.html
@@ -0,0 +1,66 @@
+<html>
+<head>
+<title>Test DataStore</title>
+<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+<script type="text/javascript">
+dojo.provide("dojox.wire.ml.tests.markup.DataStore");
+
+dojo.require("dojo.parser");
+dojo.require("doh.runner");
+dojo.require("dojox.wire.ml.DataStore");
+dojo.require("dojox.wire.ml.Invocation");
+dojo.require("dojox.wire.ml.Transfer");
+
+dojox.wire.ml.tests.markup.DataStore = {
+ request: {onComplete: function(){}, onError: function(){}}
+};
+
+dojo.addOnLoad(function(){
+ doh.register("dojox.wire.ml.tests.markup.DataStore", [
+
+ function test_DataStore_url(t){
+ var d = new doh.Deferred();
+ dojo.connect(dojox.wire.ml.tests.markup.DataStore.request, "onComplete", function(){
+ t.assertEqual("X1", dojox.wire.ml.tests.markup.DataStore.target[0].a);
+ t.assertEqual("Y2", dojox.wire.ml.tests.markup.DataStore.target[1].b);
+ t.assertEqual("Z3", dojox.wire.ml.tests.markup.DataStore.target[2].c);
+ d.callback(true);
+ });
+ dojo.connect(dojox.wire.ml.tests.markup.DataStore.request, "onError", function(error){
+ d.errback(error);
+ });
+ dojo.publish("invokeFetch");
+ return d;
+ }
+
+ ]);
+ doh.run();
+});
+</script>
+</head>
+<body>
+<div dojoType="dojox.wire.ml.DataStore"
+ id="DataStore1"
+ storeClass="dojox.data.XmlStore"
+ url="DataStore.xml"></div>
+<div dojoType="dojox.wire.ml.Invocation"
+ triggerTopic="invokeFetch"
+ object="DataStore1"
+ method="fetch"
+ parameters="dojox.wire.ml.tests.markup.DataStore.request">
+</div>
+<div dojoType="dojox.wire.ml.Transfer"
+ trigger="dojox.wire.ml.tests.markup.DataStore.request"
+ triggerEvent="onComplete"
+ source="arguments[0]"
+ sourceStore="DataStore1.store"
+ target="dojox.wire.ml.tests.markup.DataStore.target">
+ <div dojoType="dojox.wire.ml.ColumnWire"
+ column="a" attribute="x"></div>
+ <div dojoType="dojox.wire.ml.ColumnWire"
+ column="b" attribute="y"></div>
+ <div dojoType="dojox.wire.ml.ColumnWire"
+ column="c" attribute="z"></div>
+</div>
+</body>
+</html>
diff --git a/includes/js/dojox/wire/tests/markup/DataStore.xml b/includes/js/dojox/wire/tests/markup/DataStore.xml
new file mode 100644
index 0000000..eeff4c2
--- /dev/null
+++ b/includes/js/dojox/wire/tests/markup/DataStore.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<dataStore>
+ <item>
+ <x>X1</x>
+ <y>Y1</y>
+ <z>Z1</z>
+ </item>
+ <item>
+ <x>X2</x>
+ <y>Y2</y>
+ <z>Z2</z>
+ </item>
+ <item>
+ <x>X3</x>
+ <y>Y3</y>
+ <z>Z3</z>
+ </item>
+</dataStore>
diff --git a/includes/js/dojox/wire/tests/markup/Invocation.html b/includes/js/dojox/wire/tests/markup/Invocation.html
new file mode 100644
index 0000000..dd6f6e4
--- /dev/null
+++ b/includes/js/dojox/wire/tests/markup/Invocation.html
@@ -0,0 +1,53 @@
+<html>
+<head>
+<title>Test Invocation</title>
+<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad:true "></script>
+<script type="text/javascript">
+dojo.provide("dojox.wire.ml.tests.markup.Invocation");
+
+dojo.require("dojo.parser");
+dojo.require("doh.runner");
+dojo.require("dojox.wire.ml.Invocation");
+
+dojox.wire.ml.tests.markup.Invocation = {
+ invoke: function(p1, p2){return p1 + p2;},
+ invokeError: function(p){throw new Error(p);},
+ parameters: {a: "A", b: "B", c: "C"}
+};
+
+dojo.addOnLoad(function(){
+ doh.register("dojox.wire.ml.tests.markup.Invocation", [
+
+ function test_Invocation_method(t){
+ dojo.publish("invokeMethod");
+ t.assertEqual("AB", dojox.wire.ml.tests.markup.Invocation.result);
+ },
+
+ function test_Invocation_topic(t){
+ dojo.publish("invokeTopic");
+ t.assertEqual("C", dojox.wire.ml.tests.markup.Invocation.error);
+ }
+
+ ]);
+ doh.run();
+});
+</script>
+</head>
+<body>
+<div dojoType="dojox.wire.ml.Invocation"
+ triggerTopic="invokeMethod"
+ object="dojox.wire.ml.tests.markup.Invocation"
+ method="invoke"
+ parameters="dojox.wire.ml.tests.markup.Invocation.parameters.a,dojox.wire.ml.tests.markup.Invocation.parameters.b"
+ result="dojox.wire.ml.tests.markup.Invocation.result"></div>
+<div dojoType="dojox.wire.ml.Invocation"
+ triggerTopic="invokeTopic"
+ topic="invokeError"
+ parameters="dojox.wire.ml.tests.markup.Invocation.parameters.c"></div>
+<div dojoType="dojox.wire.ml.Invocation"
+ triggerTopic="invokeError"
+ object="dojox.wire.ml.tests.markup.Invocation"
+ method="invokeError"
+ error="dojox.wire.ml.tests.markup.Invocation.error"></div>
+</body>
+</html>
diff --git a/includes/js/dojox/wire/tests/markup/Service.html b/includes/js/dojox/wire/tests/markup/Service.html
new file mode 100644
index 0000000..0448c61
--- /dev/null
+++ b/includes/js/dojox/wire/tests/markup/Service.html
@@ -0,0 +1,84 @@
+<html>
+<head>
+<title>Test Service</title>
+<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+<script type="text/javascript">
+dojo.provide("dojox.wire.ml.tests.markup.Service");
+
+dojo.require("dojo.parser");
+dojo.require("doh.runner");
+dojo.require("dojox.wire.ml.Service");
+dojo.require("dojox.wire.ml.Invocation");
+dojo.require("dojox.wire.ml.Transfer");
+
+dojox.wire.ml.tests.markup.Service = {
+ query: {name: "a"}
+};
+
+dojo.addOnLoad(function(){
+ doh.register("dojox.wire.ml.tests.markup.Service", [
+
+ function test_Service_url(t){
+ var d = new doh.Deferred();
+ dojo.connect(dijit.byId("Invocation1"), "onComplete", function(result){
+ t.assertEqual("a", dojox.wire.ml.tests.markup.Service.target.a);
+ var o = result.toObject();
+ t.assertEqual("a", o.item.name); // test XmlElement.toObject()
+ t.assertEqual("b", o.item.data); // test XmlElement.toObject()
+
+ d.callback(true);
+ });
+ dojo.connect(dijit.byId("Invocation1"), "onError", function(error){
+ d.errback(error);
+ });
+ dojo.publish("invokeGetXml");
+ return d;
+ },
+
+ function test_Service_serviceUrl(t){
+ var d = new doh.Deferred();
+ dojo.connect(dijit.byId("Invocation2"), "onComplete", function(){
+ t.assertEqual("a", dojox.wire.ml.tests.markup.Service.result.item.name);
+ d.callback(true);
+ });
+ dojo.connect(dijit.byId("Invocation2"), "onError", function(error){
+ d.errback(error);
+ });
+ dojo.publish("invokeGetJson");
+ return d;
+ }
+
+ ]);
+ doh.run();
+});
+</script>
+</head>
+<body>
+<div dojoType="dojox.wire.ml.Service"
+ id="Service1"
+ url="Service/XML.smd"></div>
+<div dojoType="dojox.wire.ml.Invocation"
+ id="Invocation1"
+ triggerTopic="invokeGetXml"
+ object="Service1"
+ method="get"
+ parameters="dojox.wire.ml.tests.markup.Service.query">
+</div>
+<div dojoType="dojox.wire.ml.Transfer"
+ trigger="Invocation1"
+ triggerEvent="onComplete"
+ source="arguments[0].item.name"
+ target="dojox.wire.ml.tests.markup.Service.target.a"></div>
+<div dojoType="dojox.wire.ml.Service"
+ id="Service2"
+ serviceType="JSON"
+ serviceUrl="Service/{name}.json"></div>
+<div dojoType="dojox.wire.ml.Invocation"
+ id="Invocation2"
+ triggerTopic="invokeGetJson"
+ object="Service2"
+ method="get"
+ parameters="dojox.wire.ml.tests.markup.Service.query"
+ result="dojox.wire.ml.tests.markup.Service.result"></div>
+</body>
+</html>
diff --git a/includes/js/dojox/wire/tests/markup/Service/JSON.smd b/includes/js/dojox/wire/tests/markup/Service/JSON.smd
new file mode 100644
index 0000000..2ac9682
--- /dev/null
+++ b/includes/js/dojox/wire/tests/markup/Service/JSON.smd
@@ -0,0 +1,11 @@
+{
+ "serviceType": "JSON",
+ "serviceURL": "Service/{name}.json",
+ "methods": [{
+ "name": "get",
+ "parameters": [{
+ "name": "name",
+ "type": "str"
+ }]
+ }]
+}
diff --git a/includes/js/dojox/wire/tests/markup/Service/XML.smd b/includes/js/dojox/wire/tests/markup/Service/XML.smd
new file mode 100644
index 0000000..d833f88
--- /dev/null
+++ b/includes/js/dojox/wire/tests/markup/Service/XML.smd
@@ -0,0 +1,11 @@
+{
+ "serviceType": "XML",
+ "serviceURL": "Service/{name}.xml",
+ "methods": [{
+ "name": "get",
+ "parameters": [{
+ "name": "name",
+ "type": "str"
+ }]
+ }]
+}
diff --git a/includes/js/dojox/wire/tests/markup/Service/a.json b/includes/js/dojox/wire/tests/markup/Service/a.json
new file mode 100644
index 0000000..93fc00b
--- /dev/null
+++ b/includes/js/dojox/wire/tests/markup/Service/a.json
@@ -0,0 +1,5 @@
+{
+ "item": {
+ "name": "a"
+ }
+}
diff --git a/includes/js/dojox/wire/tests/markup/Service/a.xml b/includes/js/dojox/wire/tests/markup/Service/a.xml
new file mode 100644
index 0000000..21e4367
--- /dev/null
+++ b/includes/js/dojox/wire/tests/markup/Service/a.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<item>
+ <name>a</name>
+ <data><![CDATA[b]]></data>
+</item>
diff --git a/includes/js/dojox/wire/tests/markup/Transfer.html b/includes/js/dojox/wire/tests/markup/Transfer.html
new file mode 100644
index 0000000..3ec11a4
--- /dev/null
+++ b/includes/js/dojox/wire/tests/markup/Transfer.html
@@ -0,0 +1,157 @@
+<html>
+<head>
+<title>Test Transfer</title>
+<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+<script type="text/javascript">
+dojo.provide("dojox.wire.ml.tests.markup.Transfer");
+
+dojo.require("dojo.parser");
+dojo.require("doh.runner");
+dojo.require("dojox.data.dom");
+dojo.require("dojox.data.XmlStore");
+dojo.require("dojox.wire.ml.Action");
+dojo.require("dojox.wire.ml.Transfer");
+
+dojox.wire.ml.tests.markup.Transfer = {
+ source: {a: "A", b: "B", c: [
+ {d: "D1", e: "E1"},
+ {d: "D2", e: "E2"}
+ ]}
+};
+
+dojo.addOnLoad(function(){
+ doh.register("dojox.wire.ml.tests.markup.Transfer", [
+
+ function test_Transfer_attribute(t){
+ dojox.wire.ml.tests.markup.Transfer.store = new dojox.data.XmlStore();
+ dojox.wire.ml.tests.markup.Transfer.item = dojox.wire.ml.tests.markup.Transfer.store.newItem({tagName: "x"});
+ dojox.wire.ml.tests.markup.Transfer.target = {};
+ dojo.publish("transferData");
+ t.assertEqual(dojox.wire.ml.tests.markup.Transfer.source.a, dojox.wire.ml.tests.markup.Transfer.target.a);
+ },
+
+ function test_Transfer_path(t){
+ dojox.wire.ml.tests.markup.Transfer.element = dojox.data.dom.createDocument().createElement("x");
+ dojox.wire.ml.tests.markup.Transfer.target = {};
+ dojo.publish("transferXml");
+ t.assertEqual(dojox.wire.ml.tests.markup.Transfer.source.a, dojox.wire.ml.tests.markup.Transfer.target.a);
+ },
+
+ function test_ChildWire(t){
+ dojox.wire.ml.tests.markup.Transfer.target = {};
+ dojo.publish("transferComposite");
+ t.assertEqual(dojox.wire.ml.tests.markup.Transfer.source.a, dojox.wire.ml.tests.markup.Transfer.target.c);
+ t.assertEqual(dojox.wire.ml.tests.markup.Transfer.source.b, dojox.wire.ml.tests.markup.Transfer.target.d);
+ },
+
+ function test_ColumnWire(t){
+ dojox.wire.ml.tests.markup.Transfer.target = {};
+ dojo.publish("transferTable");
+ t.assertEqual(dojox.wire.ml.tests.markup.Transfer.source.c[0].d, dojox.wire.ml.tests.markup.Transfer.target.a[0].b);
+ t.assertEqual(dojox.wire.ml.tests.markup.Transfer.source.c[1].e, dojox.wire.ml.tests.markup.Transfer.target.a[1].c);
+ },
+
+ function test_NodeWire(t){
+ dojox.wire.ml.tests.markup.Transfer.target = {};
+ dojo.publish("transferTree");
+ t.assertEqual(dojox.wire.ml.tests.markup.Transfer.source.c[0].d, dojox.wire.ml.tests.markup.Transfer.target.a[0].title);
+ t.assertEqual(dojox.wire.ml.tests.markup.Transfer.source.c[1].e, dojox.wire.ml.tests.markup.Transfer.target.a[1].children[0].title);
+ },
+
+ function test_SegimentWire(t){
+ dojox.wire.ml.tests.markup.Transfer.target = {};
+ dojo.publish("transferText");
+ t.assertEqual("A/B", dojox.wire.ml.tests.markup.Transfer.target.c);
+ }
+
+ ]);
+ doh.run();
+});
+</script>
+</head>
+<body>
+<div dojoType="dojox.wire.ml.Action"
+ triggerTopic="transferData">
+ <div dojoType="dojox.wire.ml.Transfer"
+ source="dojox.wire.ml.tests.markup.Transfer.source.a"
+ target="dojox.wire.ml.tests.markup.Transfer.item"
+ targetStore="dojox.wire.ml.tests.markup.Transfer.store"
+ targetAttribute="y"></div>
+ <div dojoType="dojox.wire.ml.Transfer"
+ source="dojox.wire.ml.tests.markup.Transfer.item"
+ sourceStore="dojox.wire.ml.tests.markup.Transfer.store"
+ sourceAttribute="y"
+ target="dojox.wire.ml.tests.markup.Transfer.target.a"></div>
+</div>
+<div dojoType="dojox.wire.ml.Action"
+ triggerTopic="transferXml">
+ <div dojoType="dojox.wire.ml.Transfer"
+ source="dojox.wire.ml.tests.markup.Transfer.source.a"
+ target="dojox.wire.ml.tests.markup.Transfer.element"
+ targetPath="y/text()"></div>
+ <div dojoType="dojox.wire.ml.Transfer"
+ source="dojox.wire.ml.tests.markup.Transfer.element"
+ sourcePath="y/text()"
+ target="dojox.wire.ml.tests.markup.Transfer.target.a"></div>
+ <div dojoType="dojox.wire.ml.Transfer"
+ source="dojox.wire.ml.tests.markup.Transfer.source.b"
+ target="dojox.wire.ml.tests.markup.Transfer.element"
+ targetPath="y/@z"></div>
+ <div dojoType="dojox.wire.ml.Transfer"
+ source="dojox.wire.ml.tests.markup.Transfer.element"
+ sourcePath="y/@z"
+ target="dojox.wire.ml.tests.markup.Transfer.target.b"></div>
+</div>
+<div dojoType="dojox.wire.ml.Transfer"
+ triggerTopic="transferComposite"
+ source="dojox.wire.ml.tests.markup.Transfer.source"
+ target="dojox.wire.ml.tests.markup.Transfer.target">
+ <div dojoType="dojox.wire.ml.ChildWire"
+ name="x"
+ property="a"></div>
+ <div dojoType="dojox.wire.ml.ChildWire"
+ which="source"
+ name="y"
+ property="b"></div>
+ <div dojoType="dojox.wire.ml.ChildWire"
+ which="target"
+ name="x"
+ property="c"></div>
+ <div dojoType="dojox.wire.ml.ChildWire"
+ which="target"
+ name="y"
+ property="d"></div>
+</div>
+<div dojoType="dojox.wire.ml.Transfer"
+ triggerTopic="transferTable"
+ source="dojox.wire.ml.tests.markup.Transfer.source.c"
+ target="dojox.wire.ml.tests.markup.Transfer.target.a">
+ <div dojoType="dojox.wire.ml.ColumnWire"
+ column="b"
+ property="d"></div>
+ <div dojoType="dojox.wire.ml.ColumnWire"
+ column="c"
+ property="e"></div>
+</div>
+<div dojoType="dojox.wire.ml.Transfer"
+ triggerTopic="transferTree"
+ source="dojox.wire.ml.tests.markup.Transfer.source.c"
+ target="dojox.wire.ml.tests.markup.Transfer.target.a">
+ <div dojoType="dojox.wire.ml.NodeWire"
+ titleProperty="d">
+ <div dojoType="dojox.wire.ml.NodeWire"
+ titleProperty="e"></div>
+ </div>
+</div>
+<div dojoType="dojox.wire.ml.Transfer"
+ triggerTopic="transferText"
+ source="dojox.wire.ml.tests.markup.Transfer.source"
+ delimiter="/"
+ target="dojox.wire.ml.tests.markup.Transfer.target.c">
+ <div dojoType="dojox.wire.ml.SegmentWire"
+ property="a"></div>
+ <div dojoType="dojox.wire.ml.SegmentWire"
+ property="b"></div>
+</div>
+</body>
+</html>
diff --git a/includes/js/dojox/wire/tests/module.js b/includes/js/dojox/wire/tests/module.js
new file mode 100644
index 0000000..17f10c3
--- /dev/null
+++ b/includes/js/dojox/wire/tests/module.js
@@ -0,0 +1,13 @@
+if(!dojo._hasResource["dojox.wire.tests.module"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.wire.tests.module"] = true;
+dojo.provide("dojox.wire.tests.module");
+
+try{
+ dojo.require("dojox.wire.tests.wire");
+ dojo.require("dojox.wire.tests.wireml");
+}catch(e){
+ doh.debug(e);
+}
+
+
+}
diff --git a/includes/js/dojox/wire/tests/programmatic/CompositeWire.js b/includes/js/dojox/wire/tests/programmatic/CompositeWire.js
new file mode 100644
index 0000000..ae9866a
--- /dev/null
+++ b/includes/js/dojox/wire/tests/programmatic/CompositeWire.js
@@ -0,0 +1,51 @@
+if(!dojo._hasResource["dojox.wire.tests.programmatic.CompositeWire"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.wire.tests.programmatic.CompositeWire"] = true;
+dojo.provide("dojox.wire.tests.programmatic.CompositeWire");
+
+dojo.require("dojox.wire.CompositeWire");
+
+tests.register("dojox.wire.tests.programmatic.CompositeWire", [
+
+ function test_CompositeWire_children(t){
+ var source = {a: "A", b: "B"};
+ var target = {};
+ var children = {x: {property: "a"}, y: {property: "b"}};
+ var value = new dojox.wire.CompositeWire({object: source, children: children}).getValue();
+ t.assertEqual(source.a, value.x);
+ t.assertEqual(source.b, value.y);
+ new dojox.wire.CompositeWire({object: target, children: children}).setValue(value);
+ t.assertEqual(source.a, target.a);
+ t.assertEqual(source.b, target.b);
+
+ // with argument
+ target = {};
+ value = new dojox.wire.CompositeWire({children: children}).getValue(source);
+ t.assertEqual(source.a, value.x);
+ t.assertEqual(source.b, value.y);
+ new dojox.wire.CompositeWire({children: children}).setValue(value, target);
+ t.assertEqual(source.a, target.a);
+ t.assertEqual(source.b, target.b);
+
+ // by array
+ target = {};
+ children = [{property: "a"}, {property: "b"}];
+ value = new dojox.wire.CompositeWire({object: source, children: children}).getValue();
+ t.assertEqual(source.a, value[0]);
+ t.assertEqual(source.b, value[1]);
+ new dojox.wire.CompositeWire({object: target, children: children}).setValue(value);
+ t.assertEqual(source.a, target.a);
+ t.assertEqual(source.b, target.b);
+
+ // by array with argument
+ target = {};
+ value = new dojox.wire.CompositeWire({children: children}).getValue(source);
+ t.assertEqual(source.a, value[0]);
+ t.assertEqual(source.b, value[1]);
+ new dojox.wire.CompositeWire({children: children}).setValue(value, target);
+ t.assertEqual(source.a, target.a);
+ t.assertEqual(source.b, target.b);
+ }
+
+]);
+
+}
diff --git a/includes/js/dojox/wire/tests/programmatic/ConverterDynamic.js b/includes/js/dojox/wire/tests/programmatic/ConverterDynamic.js
new file mode 100644
index 0000000..2665148
--- /dev/null
+++ b/includes/js/dojox/wire/tests/programmatic/ConverterDynamic.js
@@ -0,0 +1,12 @@
+if(!dojo._hasResource["dojox.wire.tests.programmatic.ConverterDynamic"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.wire.tests.programmatic.ConverterDynamic"] = true;
+dojo.provide("dojox.wire.tests.programmatic.ConverterDynamic");
+
+dojo.declare("dojox.wire.tests.programmatic.ConverterDynamic", null, {
+ convert: function(v){
+ return v + 1;
+ }
+});
+
+
+}
diff --git a/includes/js/dojox/wire/tests/programmatic/DataWire.js b/includes/js/dojox/wire/tests/programmatic/DataWire.js
new file mode 100644
index 0000000..b146901
--- /dev/null
+++ b/includes/js/dojox/wire/tests/programmatic/DataWire.js
@@ -0,0 +1,25 @@
+if(!dojo._hasResource["dojox.wire.tests.programmatic.DataWire"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.wire.tests.programmatic.DataWire"] = true;
+dojo.provide("dojox.wire.tests.programmatic.DataWire");
+
+dojo.require("dojox.wire.DataWire");
+dojo.require("dojox.data.XmlStore");
+
+tests.register("dojox.wire.tests.programmatic.DataWire", [
+
+ function test_DataWire_attribute(t){
+ var store = new dojox.data.XmlStore();
+ var item = store.newItem({tagName: "x"});
+ new dojox.wire.DataWire({dataStore: store, object: item, attribute: "y"}).setValue("Y");
+ var value = new dojox.wire.DataWire({dataStore: store, object: item, attribute: "y"}).getValue();
+ t.assertEqual("Y", value);
+
+ // nested attribute
+ new dojox.wire.DataWire({dataStore: store, object: item, attribute: "y.z"}).setValue("Z");
+ value = new dojox.wire.DataWire({dataStore: store, object: item, attribute: "y.z"}).getValue();
+ t.assertEqual("Z", value);
+ }
+
+]);
+
+}
diff --git a/includes/js/dojox/wire/tests/programmatic/TableAdapter.js b/includes/js/dojox/wire/tests/programmatic/TableAdapter.js
new file mode 100644
index 0000000..9e6adc1
--- /dev/null
+++ b/includes/js/dojox/wire/tests/programmatic/TableAdapter.js
@@ -0,0 +1,24 @@
+if(!dojo._hasResource["dojox.wire.tests.programmatic.TableAdapter"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.wire.tests.programmatic.TableAdapter"] = true;
+dojo.provide("dojox.wire.tests.programmatic.TableAdapter");
+
+dojo.require("dojox.wire.TableAdapter");
+
+tests.register("dojox.wire.tests.programmatic.TableAdapter", [
+
+ function test_TableAdapter_columns(t){
+ var source = [
+ {a: "A1", b: "B1", c: "C1"},
+ {a: "A2", b: "B2", c: "C2"},
+ {a: "A3", b: "B3", c: "C3"}
+ ];
+ var columns = {x: {property: "a"}, y: {property: "b"}, z: {property: "c"}};
+ var value = new dojox.wire.TableAdapter({object: source, columns: columns}).getValue();
+ t.assertEqual(source[0].a, value[0].x);
+ t.assertEqual(source[1].b, value[1].y);
+ t.assertEqual(source[2].c, value[2].z);
+ }
+
+]);
+
+}
diff --git a/includes/js/dojox/wire/tests/programmatic/TextAdapter.js b/includes/js/dojox/wire/tests/programmatic/TextAdapter.js
new file mode 100644
index 0000000..1014b5c
--- /dev/null
+++ b/includes/js/dojox/wire/tests/programmatic/TextAdapter.js
@@ -0,0 +1,25 @@
+if(!dojo._hasResource["dojox.wire.tests.programmatic.TextAdapter"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.wire.tests.programmatic.TextAdapter"] = true;
+dojo.provide("dojox.wire.tests.programmatic.TextAdapter");
+
+dojo.require("dojox.wire.TextAdapter");
+
+tests.register("dojox.wire.tests.programmatic.TextAdapter", [
+
+ function test_TextAdapter_segments(t){
+ var source = {a: "a", b: "b", c: "c"};
+ var segments = [{property: "a"}, {property: "b"}, {property: "c"}];
+ var value = new dojox.wire.TextAdapter({object: source, segments: segments}).getValue();
+ t.assertEqual("abc", value);
+ },
+
+ function test_TextAdapter_delimiter(t){
+ var source = {a: "a", b: "b", c: "c"};
+ var segments = [{property: "a"}, {property: "b"}, {property: "c"}];
+ var value = new dojox.wire.TextAdapter({object: source, segments: segments, delimiter: "/"}).getValue();
+ t.assertEqual("a/b/c", value);
+ }
+
+]);
+
+}
diff --git a/includes/js/dojox/wire/tests/programmatic/TreeAdapter.js b/includes/js/dojox/wire/tests/programmatic/TreeAdapter.js
new file mode 100644
index 0000000..e1671ed
--- /dev/null
+++ b/includes/js/dojox/wire/tests/programmatic/TreeAdapter.js
@@ -0,0 +1,29 @@
+if(!dojo._hasResource["dojox.wire.tests.programmatic.TreeAdapter"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.wire.tests.programmatic.TreeAdapter"] = true;
+dojo.provide("dojox.wire.tests.programmatic.TreeAdapter");
+
+dojo.require("dojox.wire.TreeAdapter");
+
+tests.register("dojox.wire.tests.programmatic.TreeAdapter", [
+
+ function test_TreeAdapter_nodes(t){
+ var source = [
+ {a: "A1", b: "B1", c: "C1"},
+ {a: "A2", b: "B2", c: "C2"},
+ {a: "A3", b: "B3", c: "C3"}
+ ];
+ var nodes = [
+ {title: {property: "a"}, children: [
+ {node: {property: "b"}},
+ {title: {property: "c"}}
+ ]}
+ ];
+ var value = new dojox.wire.TreeAdapter({object: source, nodes: nodes}).getValue();
+ t.assertEqual(source[0].a, value[0].title);
+ t.assertEqual(source[1].b, value[1].children[0].title);
+ t.assertEqual(source[2].c, value[2].children[1].title);
+ }
+
+]);
+
+}
diff --git a/includes/js/dojox/wire/tests/programmatic/Wire.js b/includes/js/dojox/wire/tests/programmatic/Wire.js
new file mode 100644
index 0000000..25a82ec
--- /dev/null
+++ b/includes/js/dojox/wire/tests/programmatic/Wire.js
@@ -0,0 +1,123 @@
+if(!dojo._hasResource["dojox.wire.tests.programmatic.Wire"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.wire.tests.programmatic.Wire"] = true;
+dojo.provide("dojox.wire.tests.programmatic.Wire");
+dojo.require("dojox.wire.Wire");
+
+//Simple connverter class to try to use.
+dojo.declare("dojox.wire.tests.programmatic.Wire.Converter", null, {
+ convert: function(v){
+ return v + 1;
+ }
+});
+
+//Simple converter function to try to use.
+//To get it in the global namespace, gotta assign it to the
+//'window' toplevel object. Otherwise it ends up in the
+//dojo NS and can't be found.
+if (dojo.isBrowser) {
+ window["__wireTestConverterFunction"] = function(v){
+ return v + 1;
+ };
+}else{
+ var __wireTestConverterFunction = function(v){
+ return v + 1;
+ };
+}
+
+tests.register("dojox.wire.tests.programmatic.Wire", [
+
+ function test_Wire_property(t){
+ var source = {a: "A", b: {c: "B.C"}};
+ var target = {a: "a", b: {c: "b.c"}};
+ var value = new dojox.wire.Wire({object: source, property: "a"}).getValue();
+ new dojox.wire.Wire({object: target, property: "a"}).setValue(value);
+ t.assertEqual(source.a, target.a);
+
+ // child property
+ value = new dojox.wire.Wire({object: source, property: "b.c"}).getValue();
+ new dojox.wire.Wire({object: target, property: "b.c"}).setValue(value);
+ t.assertEqual(source.b.c, target.b.c);
+
+ // new property
+ target = {};
+ value = new dojox.wire.Wire({object: source, property: "a"}).getValue();
+ new dojox.wire.Wire({object: target, property: "a"}).setValue(value);
+ t.assertEqual(source.a, target.a);
+
+ // new parent and child property
+ target.b = {};
+ value = new dojox.wire.Wire({object: source, property: "b.c"}).getValue();
+ new dojox.wire.Wire({object: target, property: "b.c"}).setValue(value);
+ t.assertEqual(source.b.c, target.b.c);
+
+ // new parent and child property
+ target = {};
+ value = new dojox.wire.Wire({object: source, property: "b.c"}).getValue();
+ new dojox.wire.Wire({object: target, property: "b.c"}).setValue(value);
+ t.assertEqual(source.b.c, target.b.c);
+
+ // new array property
+ source = {a: ["A"]};
+ target = {};
+ value = new dojox.wire.Wire({object: source, property: "a[0]"}).getValue();
+ new dojox.wire.Wire({object: target, property: "a[0]"}).setValue(value);
+ t.assertEqual(source.a[0], target.a[0]);
+
+ // by getter/setter
+ source = {getA: function() { return this._a; }, _a: "A"};
+ target = {setA: function(a) { this._a = a; }};
+ value = new dojox.wire.Wire({object: source, property: "a"}).getValue();
+ new dojox.wire.Wire({object: target, property: "a"}).setValue(value);
+ t.assertEqual(source._a, target._a);
+
+ // by get/setPropertyValue
+ source = {getPropertyValue: function(p) { return this["_" + p]; }, _a: "A"};
+ target = {setPropertyValue: function(p, v) { this["_" + p] = v; }};
+ value = new dojox.wire.Wire({object: source, property: "a"}).getValue();
+ new dojox.wire.Wire({object: target, property: "a"}).setValue(value);
+ t.assertEqual(source._a, target._a);
+ },
+
+ function test_Wire_type(t){
+ var source = {a: "1"};
+ var string = new dojox.wire.Wire({object: source, property: "a"}).getValue();
+ t.assertEqual("11", string + 1);
+ var number = new dojox.wire.Wire({object: source, property: "a", type: "number"}).getValue();
+ t.assertEqual(2, number + 1);
+ },
+
+ function test_Wire_converterObject(t){
+ var source = {a: "1"};
+ var converter = {convert: function(v) { return v + 1; }};
+ var string = new dojox.wire.Wire({object: source, property: "a", converter: converter}).getValue();
+ t.assertEqual("11", string);
+ },
+
+ function test_Wire_converterFunction(t){
+ var source = {a: "1"};
+ var converter = {convert: function(v) { return v + 1; }};
+ var number = new dojox.wire.Wire({object: source, property: "a", type: "number", converter: converter.convert}).getValue();
+ t.assertEqual(2, number);
+ },
+
+ function test_Wire_converterObjectByString(t){
+ var source = {a: "1"};
+ var number = new dojox.wire.Wire({object: source, property: "a", type: "number", converter: "dojox.wire.tests.programmatic.Wire.Converter"}).getValue();
+ t.assertEqual(2, number);
+ },
+
+ function test_Wire_converterFunctionByString(t){
+ var source = {a: "1"};
+ var number = new dojox.wire.Wire({object: source, property: "a", type: "number", converter: "__wireTestConverterFunction"}).getValue();
+ t.assertEqual(2, number);
+ },
+
+ function test_Wire_converterObjectByStringDynamic(t){
+ var source = {a: "1"};
+ var number = new dojox.wire.Wire({object: source, property: "a", type: "number", converter: "dojox.wire.tests.programmatic.ConverterDynamic"}).getValue();
+ t.assertEqual(2, number);
+ }
+
+]);
+
+}
diff --git a/includes/js/dojox/wire/tests/programmatic/XmlWire.js b/includes/js/dojox/wire/tests/programmatic/XmlWire.js
new file mode 100644
index 0000000..b0772d7
--- /dev/null
+++ b/includes/js/dojox/wire/tests/programmatic/XmlWire.js
@@ -0,0 +1,32 @@
+if(!dojo._hasResource["dojox.wire.tests.programmatic.XmlWire"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.wire.tests.programmatic.XmlWire"] = true;
+dojo.provide("dojox.wire.tests.programmatic.XmlWire");
+
+dojo.require("dojox.wire.XmlWire");
+
+tests.register("dojox.wire.tests.programmatic.XmlWire", [
+
+ function test_XmlWire_path(t){
+ var object = {};
+ var wire = dojox.wire.create({object: object, property: "element"});
+ new dojox.wire.XmlWire({object: wire, path: "/x/y/text()"}).setValue("Y");
+ var value = new dojox.wire.XmlWire({object: object, property: "element", path: "y/text()"}).getValue();
+ t.assertEqual("Y", value);
+
+ // attribute
+ new dojox.wire.XmlWire({object: object, property: "element", path: "y/@z"}).setValue("Z");
+ value = new dojox.wire.XmlWire({object: wire, path: "/x/y/@z"}).getValue();
+ t.assertEqual("Z", value);
+
+ // with index
+ var document = object.element.ownerDocument;
+ var element = document.createElement("y");
+ element.appendChild(document.createTextNode("Y2"));
+ object.element.appendChild(element);
+ value = new dojox.wire.XmlWire({object: object.element, path: "y[2]/text()"}).getValue();
+ t.assertEqual("Y2", value);
+ }
+
+]);
+
+}
diff --git a/includes/js/dojox/wire/tests/programmatic/_base.js b/includes/js/dojox/wire/tests/programmatic/_base.js
new file mode 100644
index 0000000..00f9abe
--- /dev/null
+++ b/includes/js/dojox/wire/tests/programmatic/_base.js
@@ -0,0 +1,111 @@
+if(!dojo._hasResource["dojox.wire.tests.programmatic._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.wire.tests.programmatic._base"] = true;
+dojo.provide("dojox.wire.tests.programmatic._base");
+
+dojo.require("dojox.wire._base");
+
+tests.register("dojox.wire.tests.programmatic._base", [
+
+ function test_create(t){
+ var wire = dojox.wire.create({});
+ t.assertTrue(wire instanceof dojox.wire.Wire);
+
+ wire = dojox.wire.create({property: "a"});
+ t.assertTrue(wire instanceof dojox.wire.Wire);
+
+ wire = dojox.wire.create({attribute: "a"});
+ t.assertTrue(wire instanceof dojox.wire.DataWire);
+
+ wire = dojox.wire.create({path: "a"});
+ t.assertTrue(wire instanceof dojox.wire.XmlWire);
+
+ wire = dojox.wire.create({children: "a"});
+ t.assertTrue(wire instanceof dojox.wire.CompositeWire);
+
+ wire = dojox.wire.create({columns: "a"});
+ t.assertTrue(wire instanceof dojox.wire.TableAdapter);
+
+ wire = dojox.wire.create({nodes: "a"});
+ t.assertTrue(wire instanceof dojox.wire.TreeAdapter);
+
+ wire = dojox.wire.create({segments: "a"});
+ t.assertTrue(wire instanceof dojox.wire.TextAdapter);
+
+ wire = dojox.wire.create({wireClass: "dojox.wire.DataWire"});
+ t.assertTrue(wire instanceof dojox.wire.DataWire);
+ },
+
+ function test_transfer(t){
+ var source = {a: "A"};
+ var target = {};
+ dojox.wire.transfer(
+ {object: source, property: "a"},
+ {object: target, property: "a"});
+ t.assertEqual(source.a, target.a);
+ },
+
+ function test_connect(t){
+ var trigger = {transfer: function() {}, transferArgument: function() {}};
+ var source = {a: "A"};
+ var target = {};
+ dojox.wire.connect({scope: trigger, event: "transfer"},
+ {object: source, property: "a"},
+ {object: target, property: "a"});
+ trigger.transfer();
+ t.assertEqual(source.a, target.a);
+
+ // with argument
+ target = {};
+ dojox.wire.connect({scope: trigger, event: "transferArgument"},
+ {property: "[0].a"},
+ {object: target, property: "a"});
+ trigger.transferArgument(source);
+ t.assertEqual(source.a, target.a);
+
+ // by topic
+ target = {};
+ dojox.wire.connect({topic: "transfer"},
+ {object: source, property: "a"},
+ {object: target, property: "a"});
+ dojo.publish("transfer");
+ t.assertEqual(source.a, target.a);
+
+ // by topic with argument
+ target = {};
+ dojox.wire.connect({topic: "transferArgument"},
+ {property: "[0].a"},
+ {object: target, property: "a"});
+ dojo.publish("transferArgument", [source]);
+ t.assertEqual(source.a, target.a);
+ },
+
+ function test_disconnect(t){
+ var trigger = {transferDisconnect: function() {}};
+ var source = {a: "A"};
+ var target = {};
+ var connection = dojox.wire.connect({scope: trigger, event: "transferDisconnect"},
+ {object: source, property: "a"},
+ {object: target, property: "a"});
+ trigger.transferDisconnect();
+ t.assertEqual(source.a, target.a);
+ delete target.a;
+ dojox.wire.disconnect(connection);
+ trigger.transferDisconnect();
+ t.assertEqual(undefined, target.a);
+
+ // by topic
+ target = {};
+ connection = dojox.wire.connect({topic: "transferDisconnect"},
+ {object: source, property: "a"},
+ {object: target, property: "a"});
+ dojo.publish("transferDisconnect");
+ t.assertEqual(source.a, target.a);
+ delete target.a;
+ dojox.wire.disconnect(connection);
+ dojo.publish("transferDisconnect");
+ t.assertEqual(undefined, target.a);
+ }
+
+]);
+
+}
diff --git a/includes/js/dojox/wire/tests/runTests.html b/includes/js/dojox/wire/tests/runTests.html
new file mode 100644
index 0000000..f4a51de
--- /dev/null
+++ b/includes/js/dojox/wire/tests/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+ <head>
+ <title>Dojox.wire Unit Test Runner</title>
+ <meta http-equiv="REFRESH" content="0;url=../../../util/doh/runner.html?testModule=dojox.wire.tests.module"></HEAD>
+ <BODY>
+ Redirecting to D.O.H runner.
+ </BODY>
+</HTML>
diff --git a/includes/js/dojox/wire/tests/wire.js b/includes/js/dojox/wire/tests/wire.js
new file mode 100644
index 0000000..e4e2a21
--- /dev/null
+++ b/includes/js/dojox/wire/tests/wire.js
@@ -0,0 +1,18 @@
+if(!dojo._hasResource["dojox.wire.tests.wire"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.wire.tests.wire"] = true;
+dojo.provide("dojox.wire.tests.wire");
+
+try{
+ dojo.require("dojox.wire.tests.programmatic._base");
+ dojo.require("dojox.wire.tests.programmatic.Wire");
+ dojo.requireIf(dojo.isBrowser, "dojox.wire.tests.programmatic.DataWire");
+ dojo.requireIf(dojo.isBrowser, "dojox.wire.tests.programmatic.XmlWire");
+ dojo.require("dojox.wire.tests.programmatic.CompositeWire");
+ dojo.require("dojox.wire.tests.programmatic.TableAdapter");
+ dojo.require("dojox.wire.tests.programmatic.TreeAdapter");
+ dojo.require("dojox.wire.tests.programmatic.TextAdapter");
+}catch(e){
+ doh.debug(e);
+}
+
+}
diff --git a/includes/js/dojox/wire/tests/wireml.js b/includes/js/dojox/wire/tests/wireml.js
new file mode 100644
index 0000000..db47056
--- /dev/null
+++ b/includes/js/dojox/wire/tests/wireml.js
@@ -0,0 +1,18 @@
+if(!dojo._hasResource["dojox.wire.tests.wireml"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.wire.tests.wireml"] = true;
+dojo.provide("dojox.wire.tests.wireml");
+
+try{
+ if(dojo.isBrowser){
+ doh.registerUrl("dojox.wire.tests.ml.Action", dojo.moduleUrl("dojox", "wire/tests/markup/Action.html"));
+ doh.registerUrl("dojox.wire.tests.ml.Transfer", dojo.moduleUrl("dojox", "wire/tests/markup/Transfer.html"));
+ doh.registerUrl("dojox.wire.tests.ml.Invocation", dojo.moduleUrl("dojox", "wire/tests/markup/Invocation.html"));
+ doh.registerUrl("dojox.wire.tests.ml.Data", dojo.moduleUrl("dojox", "wire/tests/markup/Data.html"));
+ doh.registerUrl("dojox.wire.tests.ml.DataStore", dojo.moduleUrl("dojox", "wire/tests/markup/DataStore.html"));
+ doh.registerUrl("dojox.wire.tests.ml.Service", dojo.moduleUrl("dojox", "wire/tests/markup/Service.html"));
+ }
+}catch(e){
+ doh.debug(e);
+}
+
+}