You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by mr...@apache.org on 2006/04/14 01:47:17 UTC

svn commit: r393978 [2/25] - in /incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo: ./ demos/ demos/widget/ demos/widget/EditorTree/ demos/widget/EditorTree/static/ demos/widget/Mail/ demos/widget/images/ src/ src/alg/ ...

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/JSON.php
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/JSON.php?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/JSON.php (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/JSON.php Thu Apr 13 16:46:55 2006
@@ -0,0 +1,790 @@
+<?php
+
+/** 
+ * Converts to and from JSON format.
+ * 
+ * JSON (JavaScript Object Notation) is a lightweight data-interchange
+ * format. It is easy for humans to read and write. It is easy for machines
+ * to parse and generate. It is based on a subset of the JavaScript
+ * Programming Language, Standard ECMA-262 3rd Edition - December 1999.
+ * This feature can also be found in  Python. JSON is a text format that is
+ * completely language independent but uses conventions that are familiar
+ * to programmers of the C-family of languages, including C, C++, C#, Java,
+ * JavaScript, Perl, TCL, and many others. These properties make JSON an
+ * ideal data-interchange language.
+ * 
+ * This package provides a simple encoder and decoder for JSON notation. It
+ * is intended for use with client-side Javascript applications that make
+ * use of HTTPRequest to perform server communication functions - data can
+ * be encoded into JSON notation for use in a client-side javascript, or
+ * decoded from incoming Javascript requests. JSON format is native to
+ * Javascript, and can be directly eval()'ed with no further parsing
+ * overhead
+ *
+ * All strings should be in ASCII or UTF-8 format!
+ *
+ * LICENSE: Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met: Redistributions of source code must retain the
+ * above copyright notice, this list of conditions and the following
+ * disclaimer. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * 
+ * @category   
+ * @package     Services_JSON
+ * @author      Michal Migurski <mi...@teczno.com>
+ * @author      Matt Knapp <mdknapp[at]gmail[dot]com>
+ * @author      Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
+ * @copyright   2005 Michal Migurski
+ * @license     http://www.opensource.org/licenses/bsd-license.php
+ * @link        http://pear.php.net/pepr/pepr-proposal-show.php?id=198
+ */
+
+/**
+ * Marker constant for Services_JSON::decode(), used to flag stack state
+ */
+define('SERVICES_JSON_SLICE',   1);
+
+/**
+ * Marker constant for Services_JSON::decode(), used to flag stack state
+ */
+define('SERVICES_JSON_IN_STR',  2);
+
+/**
+ * Marker constant for Services_JSON::decode(), used to flag stack state
+ */
+define('SERVICES_JSON_IN_ARR',  3);
+
+/**
+ * Marker constant for Services_JSON::decode(), used to flag stack state
+ */
+define('SERVICES_JSON_IN_OBJ',  4);
+
+/**
+ * Marker constant for Services_JSON::decode(), used to flag stack state
+ */
+define('SERVICES_JSON_IN_CMT', 5);
+
+/**
+ * Behavior switch for Services_JSON::decode()
+ */
+define('SERVICES_JSON_LOOSE_TYPE', 16);
+
+/**
+ * Behavior switch for Services_JSON::decode()
+ */
+define('SERVICES_JSON_SUPPRESS_ERRORS', 32);
+
+/** 
+ * Converts to and from JSON format.
+ *
+ * Brief example of use:
+ *
+ * <code>
+ * // create a new instance of Services_JSON
+ * $json = new Services_JSON();
+ * 
+ * // convert a complexe value to JSON notation, and send it to the browser
+ * $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4)));
+ * $output = $json->encode($value);
+ *
+ * print($output);
+ * // prints: ["foo","bar",[1,2,"baz"],[3,[4]]]
+ * 
+ * // accept incoming POST data, assumed to be in JSON notation
+ * $input = file_get_contents('php://input', 1000000);
+ * $value = $json->decode($input);
+ * </code>
+ */
+class Services_JSON
+{
+   /**
+    * constructs a new JSON instance
+    *
+    * @param    int     $use    object behavior flags; combine with boolean-OR
+    *
+    *                           possible values:
+    *                           - SERVICES_JSON_LOOSE_TYPE:  loose typing.
+    *                                   "{...}" syntax creates associative arrays
+    *                                   instead of objects in decode().
+    *                           - SERVICES_JSON_SUPPRESS_ERRORS:  error suppression.
+    *                                   Values which can't be encoded (e.g. resources)
+    *                                   appear as NULL instead of throwing errors.
+    *                                   By default, a deeply-nested resource will
+    *                                   bubble up with an error, so all return values
+    *                                   from encode() should be checked with isError()
+    */
+    function Services_JSON($use = 0)
+    {
+        $this->use = $use;
+    }
+
+   /**
+    * convert a string from one UTF-16 char to one UTF-8 char
+    *
+    * Normally should be handled by mb_convert_encoding, but
+    * provides a slower PHP-only method for installations
+    * that lack the multibye string extension.
+    *
+    * @param    string  $utf16  UTF-16 character
+    * @return   string  UTF-8 character
+    * @access   private
+    */
+    function utf162utf8($utf16)
+    {
+        // oh please oh please oh please oh please oh please
+        if(function_exists('mb_convert_encoding'))
+            return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
+        
+        $bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
+
+        switch(true) {
+            case ((0x7F & $bytes) == $bytes):
+                // this case should never be reached, because we are in ASCII range
+                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                return chr(0x7F & $bytes);
+
+            case (0x07FF & $bytes) == $bytes:
+                // return a 2-byte UTF-8 character
+                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                return chr(0xC0 | (($bytes >> 6) & 0x1F))
+                     . chr(0x80 | ($bytes & 0x3F));
+
+            case (0xFFFF & $bytes) == $bytes:
+                // return a 3-byte UTF-8 character
+                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                return chr(0xE0 | (($bytes >> 12) & 0x0F))
+                     . chr(0x80 | (($bytes >> 6) & 0x3F))
+                     . chr(0x80 | ($bytes & 0x3F));
+        }
+
+        // ignoring UTF-32 for now, sorry
+        return '';
+    }        
+
+   /**
+    * convert a string from one UTF-8 char to one UTF-16 char
+    *
+    * Normally should be handled by mb_convert_encoding, but
+    * provides a slower PHP-only method for installations
+    * that lack the multibye string extension.
+    *
+    * @param    string  $utf8   UTF-8 character
+    * @return   string  UTF-16 character
+    * @access   private
+    */
+    function utf82utf16($utf8)
+    {
+        // oh please oh please oh please oh please oh please
+        if(function_exists('mb_convert_encoding'))
+            return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
+        
+        switch(strlen($utf8)) {
+            case 1:
+                // this case should never be reached, because we are in ASCII range
+                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                return $ut8;
+
+            case 2:
+                // return a UTF-16 character from a 2-byte UTF-8 char
+                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                return chr(0x07 & (ord($utf8{0}) >> 2))
+                     . chr((0xC0 & (ord($utf8{0}) << 6))
+                         | (0x3F & ord($utf8{1})));
+                
+            case 3:
+                // return a UTF-16 character from a 3-byte UTF-8 char
+                // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                return chr((0xF0 & (ord($utf8{0}) << 4))
+                         | (0x0F & (ord($utf8{1}) >> 2)))
+                     . chr((0xC0 & (ord($utf8{1}) << 6))
+                         | (0x7F & ord($utf8{2})));
+        }
+
+        // ignoring UTF-32 for now, sorry
+        return '';
+    }        
+
+   /**
+    * encodes an arbitrary variable into JSON format
+    *
+    * @param    mixed   $var    any number, boolean, string, array, or object to be encoded.
+    *                           see argument 1 to Services_JSON() above for array-parsing behavior.
+    *                           if var is a strng, note that encode() always expects it
+    *                           to be in ASCII or UTF-8 format!
+    *
+    * @return   mixed   JSON string representation of input var or an error if a problem occurs
+    * @access   public
+    */
+    function encode($var)
+    {
+        switch (gettype($var)) {
+            case 'boolean':
+                return $var ? 'true' : 'false';
+            
+            case 'NULL':
+                return 'null';
+            
+            case 'integer':
+                return (int) $var;
+                
+            case 'double':
+            case 'float':
+                return (float) $var;
+                
+            case 'string':
+                // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
+                $ascii = '';
+                $strlen_var = strlen($var);
+
+               /*
+                * Iterate over every character in the string,
+                * escaping with a slash or encoding to UTF-8 where necessary
+                */
+                for ($c = 0; $c < $strlen_var; ++$c) {
+                    
+                    $ord_var_c = ord($var{$c});
+                    
+                    switch (true) {
+                        case $ord_var_c == 0x08:
+                            $ascii .= '\b';
+                            break;
+                        case $ord_var_c == 0x09:
+                            $ascii .= '\t';
+                            break;
+                        case $ord_var_c == 0x0A:
+                            $ascii .= '\n';
+                            break;
+                        case $ord_var_c == 0x0C:
+                            $ascii .= '\f';
+                            break;
+                        case $ord_var_c == 0x0D:
+                            $ascii .= '\r';
+                            break;
+
+                        case $ord_var_c == 0x22:
+                        case $ord_var_c == 0x2F:
+                        case $ord_var_c == 0x5C:
+                            // double quote, slash, slosh
+                            $ascii .= '\\'.$var{$c};
+                            break;
+                            
+                        case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
+                            // characters U-00000000 - U-0000007F (same as ASCII)
+                            $ascii .= $var{$c};
+                            break;
+                        
+                        case (($ord_var_c & 0xE0) == 0xC0):
+                            // characters U-00000080 - U-000007FF, mask 110XXXXX
+                            // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                            $char = pack('C*', $ord_var_c, ord($var{$c + 1}));
+                            $c += 1;
+                            $utf16 = $this->utf82utf16($char);
+                            $ascii .= sprintf('\u%04s', bin2hex($utf16));
+                            break;
+    
+                        case (($ord_var_c & 0xF0) == 0xE0):
+                            // characters U-00000800 - U-0000FFFF, mask 1110XXXX
+                            // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                            $char = pack('C*', $ord_var_c,
+                                         ord($var{$c + 1}),
+                                         ord($var{$c + 2}));
+                            $c += 2;
+                            $utf16 = $this->utf82utf16($char);
+                            $ascii .= sprintf('\u%04s', bin2hex($utf16));
+                            break;
+    
+                        case (($ord_var_c & 0xF8) == 0xF0):
+                            // characters U-00010000 - U-001FFFFF, mask 11110XXX
+                            // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                            $char = pack('C*', $ord_var_c,
+                                         ord($var{$c + 1}),
+                                         ord($var{$c + 2}),
+                                         ord($var{$c + 3}));
+                            $c += 3;
+                            $utf16 = $this->utf82utf16($char);
+                            $ascii .= sprintf('\u%04s', bin2hex($utf16));
+                            break;
+    
+                        case (($ord_var_c & 0xFC) == 0xF8):
+                            // characters U-00200000 - U-03FFFFFF, mask 111110XX
+                            // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                            $char = pack('C*', $ord_var_c,
+                                         ord($var{$c + 1}),
+                                         ord($var{$c + 2}),
+                                         ord($var{$c + 3}),
+                                         ord($var{$c + 4}));
+                            $c += 4;
+                            $utf16 = $this->utf82utf16($char);
+                            $ascii .= sprintf('\u%04s', bin2hex($utf16));
+                            break;
+    
+                        case (($ord_var_c & 0xFE) == 0xFC):
+                            // characters U-04000000 - U-7FFFFFFF, mask 1111110X
+                            // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                            $char = pack('C*', $ord_var_c,
+                                         ord($var{$c + 1}),
+                                         ord($var{$c + 2}),
+                                         ord($var{$c + 3}),
+                                         ord($var{$c + 4}),
+                                         ord($var{$c + 5}));
+                            $c += 5;
+                            $utf16 = $this->utf82utf16($char);
+                            $ascii .= sprintf('\u%04s', bin2hex($utf16));
+                            break;
+                    }
+                }
+                
+                return '"'.$ascii.'"';
+                
+            case 'array':
+               /*
+                * As per JSON spec if any array key is not an integer
+                * we must treat the the whole array as an object. We
+                * also try to catch a sparsely populated associative
+                * array with numeric keys here because some JS engines
+                * will create an array with empty indexes up to
+                * max_index which can cause memory issues and because
+                * the keys, which may be relevant, will be remapped
+                * otherwise.
+                * 
+                * As per the ECMA and JSON specification an object may
+                * have any string as a property. Unfortunately due to
+                * a hole in the ECMA specification if the key is a
+                * ECMA reserved word or starts with a digit the
+                * parameter is only accessible using ECMAScript's
+                * bracket notation.
+                */
+                
+                // treat as a JSON object  
+                if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
+                    $properties = array_map(array($this, 'name_value'),
+                                            array_keys($var),
+                                            array_values($var));
+                
+                    foreach($properties as $property)
+                        if(Services_JSON::isError($property))
+                            return $property;
+                    
+                    return '{' . join(',', $properties) . '}';
+                }
+
+                // treat it like a regular array
+                $elements = array_map(array($this, 'encode'), $var);
+                
+                foreach($elements as $element)
+                    if(Services_JSON::isError($element))
+                        return $element;
+                
+                return '[' . join(',', $elements) . ']';
+                
+            case 'object':
+                $vars = get_object_vars($var);
+
+                $properties = array_map(array($this, 'name_value'),
+                                        array_keys($vars),
+                                        array_values($vars));
+            
+                foreach($properties as $property)
+                    if(Services_JSON::isError($property))
+                        return $property;
+                
+                return '{' . join(',', $properties) . '}';
+
+            default:
+                return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)
+                    ? 'null'
+                    : new Services_JSON_Error(gettype($var)." can not be encoded as JSON string");
+        }
+    }
+    
+   /**
+    * array-walking function for use in generating JSON-formatted name-value pairs
+    *
+    * @param    string  $name   name of key to use
+    * @param    mixed   $value  reference to an array element to be encoded
+    *
+    * @return   string  JSON-formatted name-value pair, like '"name":value'
+    * @access   private
+    */
+    function name_value($name, $value)
+    {
+        $encoded_value = $this->encode($value);
+        
+        if(Services_JSON::isError($encoded_value))
+            return $encoded_value;
+    
+        return $this->encode(strval($name)) . ':' . $encoded_value;
+    }        
+
+   /**
+    * reduce a string by removing leading and trailing comments and whitespace
+    *
+    * @param    $str    string      string value to strip of comments and whitespace
+    *
+    * @return   string  string value stripped of comments and whitespace
+    * @access   private
+    */
+    function reduce_string($str)
+    {
+        $str = preg_replace(array(
+        
+                // eliminate single line comments in '// ...' form
+                '#^\s*//(.+)$#m',
+    
+                // eliminate multi-line comments in '/* ... */' form, at start of string
+                '#^\s*/\*(.+)\*/#Us',
+    
+                // eliminate multi-line comments in '/* ... */' form, at end of string
+                '#/\*(.+)\*/\s*$#Us'
+    
+            ), '', $str);
+        
+        // eliminate extraneous space
+        return trim($str);
+    }
+
+   /**
+    * decodes a JSON string into appropriate variable
+    *
+    * @param    string  $str    JSON-formatted string
+    *
+    * @return   mixed   number, boolean, string, array, or object
+    *                   corresponding to given JSON input string.
+    *                   See argument 1 to Services_JSON() above for object-output behavior.
+    *                   Note that decode() always returns strings
+    *                   in ASCII or UTF-8 format!
+    * @access   public
+    */
+    function decode($str)
+    {
+        $str = $this->reduce_string($str);
+    
+        switch (strtolower($str)) {
+            case 'true':
+                return true;
+
+            case 'false':
+                return false;
+            
+            case 'null':
+                return null;
+            
+            default:
+                if (is_numeric($str)) {
+                    // Lookie-loo, it's a number
+
+                    // This would work on its own, but I'm trying to be
+                    // good about returning integers where appropriate:
+                    // return (float)$str;
+
+                    // Return float or int, as appropriate
+                    return ((float)$str == (integer)$str)
+                        ? (integer)$str
+                        : (float)$str;
+                    
+                } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
+                    // STRINGS RETURNED IN UTF-8 FORMAT
+                    $delim = substr($str, 0, 1);
+                    $chrs = substr($str, 1, -1);
+                    $utf8 = '';
+                    $strlen_chrs = strlen($chrs);
+                    
+                    for ($c = 0; $c < $strlen_chrs; ++$c) {
+                    
+                        $substr_chrs_c_2 = substr($chrs, $c, 2);
+                        $ord_chrs_c = ord($chrs{$c});
+                        
+                        switch (true) {
+                            case $substr_chrs_c_2 == '\b':
+                                $utf8 .= chr(0x08);
+                                ++$c;
+                                break;
+                            case $substr_chrs_c_2 == '\t':
+                                $utf8 .= chr(0x09);
+                                ++$c;
+                                break;
+                            case $substr_chrs_c_2 == '\n':
+                                $utf8 .= chr(0x0A);
+                                ++$c;
+                                break;
+                            case $substr_chrs_c_2 == '\f':
+                                $utf8 .= chr(0x0C);
+                                ++$c;
+                                break;
+                            case $substr_chrs_c_2 == '\r':
+                                $utf8 .= chr(0x0D);
+                                ++$c;
+                                break;
+
+                            case $substr_chrs_c_2 == '\\"':
+                            case $substr_chrs_c_2 == '\\\'':
+                            case $substr_chrs_c_2 == '\\\\':
+                            case $substr_chrs_c_2 == '\\/':
+                                if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
+                                   ($delim == "'" && $substr_chrs_c_2 != '\\"')) {
+                                    $utf8 .= $chrs{++$c};
+                                }
+                                break;
+                                
+                            case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
+                                // single, escaped unicode character
+                                $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
+                                       . chr(hexdec(substr($chrs, ($c + 4), 2)));
+                                $utf8 .= $this->utf162utf8($utf16);
+                                $c += 5;
+                                break;
+        
+                            case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
+                                $utf8 .= $chrs{$c};
+                                break;
+        
+                            case ($ord_chrs_c & 0xE0) == 0xC0:
+                                // characters U-00000080 - U-000007FF, mask 110XXXXX
+                                //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                                $utf8 .= substr($chrs, $c, 2);
+                                ++$c;
+                                break;
+    
+                            case ($ord_chrs_c & 0xF0) == 0xE0:
+                                // characters U-00000800 - U-0000FFFF, mask 1110XXXX
+                                // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                                $utf8 .= substr($chrs, $c, 3);
+                                $c += 2;
+                                break;
+    
+                            case ($ord_chrs_c & 0xF8) == 0xF0:
+                                // characters U-00010000 - U-001FFFFF, mask 11110XXX
+                                // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                                $utf8 .= substr($chrs, $c, 4);
+                                $c += 3;
+                                break;
+    
+                            case ($ord_chrs_c & 0xFC) == 0xF8:
+                                // characters U-00200000 - U-03FFFFFF, mask 111110XX
+                                // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                                $utf8 .= substr($chrs, $c, 5);
+                                $c += 4;
+                                break;
+    
+                            case ($ord_chrs_c & 0xFE) == 0xFC:
+                                // characters U-04000000 - U-7FFFFFFF, mask 1111110X
+                                // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+                                $utf8 .= substr($chrs, $c, 6);
+                                $c += 5;
+                                break;
+
+                        }
+
+                    }
+                    
+                    return $utf8;
+                
+                } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
+                    // array, or object notation
+
+                    if ($str{0} == '[') {
+                        $stk = array(SERVICES_JSON_IN_ARR);
+                        $arr = array();
+                    } else {
+                        if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
+                            $stk = array(SERVICES_JSON_IN_OBJ);
+                            $obj = array();
+                        } else {
+                            $stk = array(SERVICES_JSON_IN_OBJ);
+                            $obj = new stdClass();
+                        }
+                    }
+                    
+                    array_push($stk, array('what'  => SERVICES_JSON_SLICE,
+                                           'where' => 0,
+                                           'delim' => false));
+
+                    $chrs = substr($str, 1, -1);
+                    $chrs = $this->reduce_string($chrs);
+                    
+                    if ($chrs == '') {
+                        if (reset($stk) == SERVICES_JSON_IN_ARR) {
+                            return $arr;
+
+                        } else {
+                            return $obj;
+
+                        }
+                    }
+
+                    //print("\nparsing {$chrs}\n");
+                    
+                    $strlen_chrs = strlen($chrs);
+                    
+                    for ($c = 0; $c <= $strlen_chrs; ++$c) {
+                    
+                        $top = end($stk);
+                        $substr_chrs_c_2 = substr($chrs, $c, 2);
+                    
+                        if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {
+                            // found a comma that is not inside a string, array, etc.,
+                            // OR we've reached the end of the character list
+                            $slice = substr($chrs, $top['where'], ($c - $top['where']));
+                            array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
+                            //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+                            if (reset($stk) == SERVICES_JSON_IN_ARR) {
+                                // we are in an array, so just push an element onto the stack
+                                array_push($arr, $this->decode($slice));
+
+                            } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
+                                // we are in an object, so figure
+                                // out the property name and set an
+                                // element in an associative array,
+                                // for now
+                                if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
+                                    // "name":value pair
+                                    $key = $this->decode($parts[1]);
+                                    $val = $this->decode($parts[2]);
+
+                                    if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
+                                        $obj[$key] = $val;
+                                    } else {
+                                        $obj->$key = $val;
+                                    }
+                                } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
+                                    // name:value pair, where name is unquoted
+                                    $key = $parts[1];
+                                    $val = $this->decode($parts[2]);
+
+                                    if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
+                                        $obj[$key] = $val;
+                                    } else {
+                                        $obj->$key = $val;
+                                    }
+                                }
+
+                            }
+
+                        } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) {
+                            // found a quote, and we are not inside a string
+                            array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
+                            //print("Found start of string at {$c}\n");
+
+                        } elseif (($chrs{$c} == $top['delim']) &&
+                                 ($top['what'] == SERVICES_JSON_IN_STR) &&
+                                 (($chrs{$c - 1} != '\\') ||
+                                 ($chrs{$c - 1} == '\\' && $chrs{$c - 2} == '\\'))) {
+                            // found a quote, we're in a string, and it's not escaped
+                            array_pop($stk);
+                            //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
+
+                        } elseif (($chrs{$c} == '[') &&
+                                 in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
+                            // found a left-bracket, and we are in an array, object, or slice
+                            array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));
+                            //print("Found start of array at {$c}\n");
+
+                        } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {
+                            // found a right-bracket, and we're in an array
+                            array_pop($stk);
+                            //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+                        } elseif (($chrs{$c} == '{') &&
+                                 in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
+                            // found a left-brace, and we are in an array, object, or slice
+                            array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));
+                            //print("Found start of object at {$c}\n");
+
+                        } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {
+                            // found a right-brace, and we're in an object
+                            array_pop($stk);
+                            //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+                        } elseif (($substr_chrs_c_2 == '/*') &&
+                                 in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
+                            // found a comment start, and we are in an array, object, or slice
+                            array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));
+                            $c++;
+                            //print("Found start of comment at {$c}\n");
+
+                        } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) {
+                            // found a comment end, and we're in one now
+                            array_pop($stk);
+                            $c++;
+                            
+                            for ($i = $top['where']; $i <= $c; ++$i)
+                                $chrs = substr_replace($chrs, ' ', $i, 1);
+                            
+                            //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+                        }
+                    
+                    }
+                    
+                    if (reset($stk) == SERVICES_JSON_IN_ARR) {
+                        return $arr;
+
+                    } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
+                        return $obj;
+
+                    }
+                
+                }
+        }
+    }
+    
+    /**
+     * @todo Ultimately, this should just call PEAR::isError()
+     */
+    function isError($data, $code = null)
+    {
+        if (class_exists('pear')) {
+            return PEAR::isError($data, $code);
+        } elseif (is_object($data) && (get_class($data) == 'services_json_error' ||
+                                 is_subclass_of($data, 'services_json_error'))) {
+            return true;
+        }
+
+        return false;
+    }
+}
+
+if (class_exists('pear_error')) {
+
+    class Services_JSON_Error extends PEAR_Error
+    {
+        function Services_JSON_Error($message = 'unknown error', $code = null,
+                                     $mode = null, $options = null, $userinfo = null)
+        {
+            parent::PEAR_Error($message, $code, $mode, $options, $userinfo);
+        }
+    }
+
+} else {
+
+    /**
+     * @todo Ultimately, this class shall be descended from PEAR_Error
+     */
+    class Services_JSON_Error
+    {
+        function Services_JSON_Error($message = 'unknown error', $code = null,
+                                     $mode = null, $options = null, $userinfo = null)
+        {
+        
+        }
+    }
+
+}
+    
+?>
\ No newline at end of file

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/changeParent
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/changeParent?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/changeParent (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/changeParent Thu Apr 13 16:46:55 2006
@@ -0,0 +1 @@
+true
\ No newline at end of file

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/createNode
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/createNode?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/createNode (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/createNode Thu Apr 13 16:46:55 2006
@@ -0,0 +1 @@
+{title:"New node"}
\ No newline at end of file

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/getChildren
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/getChildren?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/getChildren (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/getChildren Thu Apr 13 16:46:55 2006
@@ -0,0 +1 @@
+[{title:"test",isFolder:true},{title:"test2"}]
\ No newline at end of file

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/json_tree.php
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/json_tree.php?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/json_tree.php (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/json_tree.php Thu Apr 13 16:46:55 2006
@@ -0,0 +1,47 @@
+<?php
+
+//sleep(1); # enable to see loading process
+
+include_once 'JSON.php';
+
+$json = new Services_JSON();
+
+header('Content-Type: text/json');
+
+if ($_REQUEST['action'] == 'getChildren') {
+	$child1 = array(
+		'title'=>'test',
+		'isFolder'=>true,
+		'widgetId'=>rand(10,10000),
+	);
+	$child2 = array(
+		'title'=>'test2',
+		'widgetId'=>rand(10,10000),
+	);
+
+	echo $json->encode(array($child1, $child2));
+
+}
+
+if ($_REQUEST['action'] == 'changeParent') {
+	echo "true";
+}
+
+if ($_REQUEST['action'] == 'swapNodes') {
+	echo "true";
+}
+
+
+if ($_REQUEST['action'] == 'removeNode') {
+	echo "true";
+}
+
+if ($_REQUEST['action'] == 'createNode') {
+	$data = $json->decode(@$_REQUEST['data']); // maybe no data at all
+	$response = array(
+		'title'=>$data->suggestedTitle,
+		'widgetId'=>rand(10,10000),
+	);
+	echo $json->encode($response);
+}
+

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/removeNode
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/removeNode?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/removeNode (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/removeNode Thu Apr 13 16:46:55 2006
@@ -0,0 +1 @@
+true
\ No newline at end of file

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/static/create.gif
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/static/create.gif?rev=393978&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/static/create.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/static/createsmall.gif
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/static/createsmall.gif?rev=393978&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/static/createsmall.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/static/down.gif
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/static/down.gif?rev=393978&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/static/down.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/static/downsmall.png
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/static/downsmall.png?rev=393978&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/static/downsmall.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/static/loading.jpg
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/static/loading.jpg?rev=393978&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/static/loading.jpg
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/static/recyclebin.gif
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/static/recyclebin.gif?rev=393978&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/static/recyclebin.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/static/removesmall.gif
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/static/removesmall.gif?rev=393978&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/static/removesmall.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/static/up.gif
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/static/up.gif?rev=393978&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/static/up.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/static/upsmall.png
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/static/upsmall.png?rev=393978&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/static/upsmall.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/swapNodes
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/swapNodes?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/swapNodes (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/swapNodes Thu Apr 13 16:46:55 2006
@@ -0,0 +1 @@
+true
\ No newline at end of file

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/tree.html
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/tree.html?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/tree.html (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/EditorTree/tree.html Thu Apr 13 16:46:55 2006
@@ -0,0 +1,352 @@
+<html>
+<head>
+<title>Dojo EditorTree Widget Test (ajax, drag'n'drop and more)</title>
+
+<script type="text/javascript">
+	var djConfig = {isDebug: true};
+	//var djConfig = {isDebug: true, debugAtAllCosts: true };
+</script>
+<script type="text/javascript" src="../../../dojo.js"></script>
+
+<script type="text/javascript">
+	dojo.require("dojo.lang.*");
+	dojo.require("dojo.widget.EditorTree");
+	dojo.require("dojo.widget.EditorTreeController");
+	dojo.require("dojo.widget.EditorTreeSelector");
+	dojo.require("dojo.widget.EditorTreeNode");
+	dojo.require("dojo.widget.EditorTreeContextMenu");
+	dojo.require("dojo.widget.DebugConsole");
+	dojo.require("dojo.widget.ResizeHandle");
+	dojo.require("dojo.widget.Button2");
+
+
+	dojo.hostenv.writeIncludes();
+
+	function restoreIconSrc() {
+		this.icon.src = this.oldIconSrc;
+	}
+
+
+	/* process up or down operation */
+	function moveClicked(selectedNode, controllerId, icon, direction) {
+		this.icon = icon;
+		this.oldIconSrc = icon.src;
+
+		this.controller = dojo.widget.manager.getWidgetById(controllerId);
+
+		if (!selectedNode) {
+			alert('No node selected');
+			return false;
+		}
+
+		this.icon.src = 'static/loading.jpg';
+
+		var mover = (direction == 'up') ? controller.moveUp : controller.moveDown;
+
+		var res = mover.apply(controller, [selectedNode, dojo.lang.hitch(this, restoreIconSrc)]);
+
+		// local checks failed
+		if (res == false) {
+			restoreIconSrc.apply(this);
+		}
+	}
+
+	/* process create operation */
+	function createClicked(selectedNode, controllerId, icon) {
+		this.icon = icon;
+		this.oldIconSrc = icon.src;
+
+		this.controller = dojo.widget.manager.getWidgetById(controllerId);
+
+		if (!selectedNode || !selectedNode.isFolder) {
+			alert('Select folder please');
+			return false;
+		}
+
+		this.icon.src = 'static/loading.jpg';
+
+		// I send some data to server and recieve feedback with right node
+		var res = controller.createNode(selectedNode, 0, { suggestedTitle: "New node" }, dojo.lang.hitch(this, restoreIconSrc));
+
+		// local checks failed
+		if (res == false) {
+			restoreIconSrc.apply(this);
+		}
+	}
+
+	function deleteClicked(selectedNode, controllerId, icon) {
+
+		this.icon = icon;
+		this.oldIconSrc = icon.src;
+
+		this.controller = dojo.widget.manager.getWidgetById(controllerId);
+
+		if (!selectedNode) {
+			alert('No node selected');
+			return false;
+		}
+
+		this.icon.src = 'static/loading.jpg';
+
+		var res = controller.removeNode(selectedNode, dojo.lang.hitch(this, restoreIconSrc));
+
+		// local checks failed
+		if (res == false) {
+			restoreIconSrc.apply(this);
+		}
+
+
+	}
+
+	var handler = function(reporter) {
+					this.name = eventName;
+					this.go = function(message) {
+						var rep = [ reporter + " -- event: "+this.name ];
+						for(i in message) rep.push(i+": "+message[i]);
+						dojo.debug(rep.join(', '));
+					}
+				}
+
+	dojo.addOnLoad(function(){
+
+
+		/* Add debug print for all controller events */
+		var controller = dojo.widget.manager.getWidgetById('treeController');
+		for(eventName in controller.eventNames) {
+			dojo.event.topic.subscribe(
+				controller.eventNames[eventName],
+				new handler('controller'),
+				'go'
+			);
+		}
+
+		/* Add debug print for all firstTree events */
+		var firstTree = dojo.widget.manager.getWidgetById('firstTree');
+
+
+		for(eventName in firstTree.eventNames) {
+			dojo.event.topic.subscribe(
+				firstTree.eventNames[eventName],
+				new handler('firstTree'),
+				'go'
+			);
+		}
+
+		/* Add debug print for all secondTree events */
+		var secondTree = dojo.widget.manager.getWidgetById('secondTree');
+		for(eventName in secondTree.eventNames) {
+			dojo.event.topic.subscribe(
+				secondTree.eventNames[eventName],
+				new handler('secondTree'),
+				'go'
+			);
+		}
+
+
+		/* add context menu to all nodes of firstTree that exist already*/
+		var nodes = firstTree.getDescendants();
+		var menu = dojo.widget.manager.getWidgetById('treeContextMenu');
+		for(var i=0; i<nodes.length; i++) {
+			if (nodes[i].widgetType != 'EditorTreeNode') continue;
+			menu.bindDomNode(nodes[i].labelNode);
+		}
+
+		/* bind context menu to all nodes that will be created in the future (e.g loaded from server) */
+
+		dojo.event.topic.subscribe(firstTree.eventNames.nodeCreate,
+			function(message) { menu.bindDomNode(message.source.labelNode); }
+		);
+
+		/* handle drags between trees.. Wire/unwire context menu if needed */
+		var controller = dojo.widget.manager.getWidgetById('treeController');
+		dojo.event.topic.subscribe(controller.eventNames.move,
+			function(message) {
+				if (message.oldParent.tree === message.newParent.tree) return; // same tree, nothing to be done
+				if (message.newParent.tree.widgetId != 'firstTree') { // only first tree has context menu
+					dojo.lang.forEach(message.child.getDescendants(), function(child) { menu.unBindDomNode(child.labelNode); });
+				}
+				if (message.newParent.tree.widgetId == 'firstTree') {
+					dojo.lang.forEach(message.child.getDescendants(), function(child) { menu.bindDomNode(child.labelNode); });
+				}
+			}
+		);
+
+
+
+	});
+
+
+	function onCreate(menuitem) {
+		var treeNode = menuitem.getTreeNode();
+		createClicked(treeNode, 'treeController', treeNode.expandIcon);
+	}
+
+	function onRemove(menuitem) {
+		var treeNode = menuitem.getTreeNode();
+		deleteClicked(treeNode, 'treeController', treeNode.expandIcon);
+	}
+
+	function onUp(menuitem) {
+		var treeNode = menuitem.getTreeNode();
+		moveClicked(treeNode, 'treeController', treeNode.expandIcon, 'up');
+	}
+
+	function onDown(menuitem) {
+		var treeNode = menuitem.getTreeNode();
+		moveClicked(treeNode, 'treeController', treeNode.expandIcon, 'down');
+	}
+
+</script>
+
+</head>
+<body>
+
+<!--
+	Controller is not a real widget. But I need to bind it to the tree in the moment of creations,
+	so I use this syntax. Waiting for dojo:propertySet
+-->
+<div dojoType="EditorTreeController" widgetId="treeController" eventNaming="default" enabledDND="true"></div>
+
+<div dojoType="EditorTreeSelector" widgetId="treeSelector"></div>
+
+
+<div dojoType="EditorTreeContextMenu" toggle="explode" eventNaming="default" contextMenuForWindow="false" widgetId="treeContextMenu">
+	<div dojoType="EditorTreeMenuItem" for_folders="false" iconSrc="static/createsmall.gif" caption="Create" onclick="onCreate(this);"></div>
+	<div dojoType="EditorTreeMenuItem" iconSrc="static/removesmall.gif" caption="Remove" onclick="onRemove(this);"></div>
+	<div dojoType="EditorTreeMenuItem" iconSrc="static/downsmall.png" caption="Up" onClick="onUp(this)"></div>
+	<div dojoType="EditorTreeMenuItem" iconSrc="static/upsmall.png" caption="Down" onClick="onDown(this)"></div>
+</div>
+
+
+<style>
+#toolsDiv img {
+	vertical-align: middle;
+}
+.treeTable tr {
+	vertical-align: top;
+}
+</style>
+<!--
+	A sample toolbar
+-->
+<div id="toolsDiv">
+<img src="static/create.gif" onclick="createClicked(dojo.widget.manager.getWidgetById('treeSelector').selectedNode,'treeController', this);"/>
+<img src="static/up.gif" onclick="moveClicked(dojo.widget.manager.getWidgetById('treeSelector').selectedNode,'treeController', this, 'up');"/>
+<img src="static/down.gif" onclick="moveClicked(dojo.widget.manager.getWidgetById('treeSelector').selectedNode,'treeController', this, 'down');"/>
+<img src="static/recyclebin.gif" onclick="deleteClicked(dojo.widget.manager.getWidgetById('treeSelector').selectedNode, 'treeController', this);"/>
+
+</div>
+<hr/>
+
+<!--
+<div dojoType="DebugConsole"
+	title="Debug Console"
+	constrainToContainer="1"
+	style="width: 400px; height: 300px; left: 200px;"
+	hasShadow="true"
+	resizable="true"
+	displayCloseAction="true"
+	layoutAlign="client"
+>
+</div>
+-->
+
+<!--
+	Every node must have widgetId to get recognized by server (ajax)
+	!!! wipe toggle from widget.Tree is buggy in FF (try open a lot of nodes)
+-->
+<table class="treeTable" cellpadding="10">
+<tr>
+<td style="border:1px dashed black">
+<h4>firstTree</h4>
+<div dojoType="EditorTree" toggle="default" selector="treeSelector" eventNaming="default" widgetId="firstTree" acceptDropSources="secondTree" controller="treeController">
+
+    <div dojoType="EditorTreeNode" title="Item 1.1" widgetId="1.1">
+
+       	<div dojoType="EditorTreeNode" widgetId="1.1.1" title="Item 1.1.1" isFolder="true"></div>
+
+    </div>
+
+	<div dojoType="EditorTreeNode" widgetId="1.2" title="Item 1.2"></div>
+	<div dojoType="EditorTreeNode" widgetId="1.3" title="Item 1.3" isFolder="true"></div>
+
+</div>
+</td>
+<td style="border:1px dashed black">
+<h4>secondTree</h4>
+<div dojoType="EditorTree" toggle="default" selector="treeSelector" eventNaming="default" widgetId="secondTree" acceptDropSources="secondTree,firstTree"  controller="treeController">
+
+    <div dojoType="EditorTreeNode" title="Item 2.1" widgetId="2.1" isFolder="true"></div>
+    <div dojoType="EditorTreeNode" title="Item 2.2" widgetId="2.2" isFolder="true"></div>
+
+</div>
+</td>
+</tr>
+</table>
+
+
+
+<hr>
+
+
+<h3>The tree should provide most functionality requested by apps.<br/>
+Read the description about it.<br/>
+Also, if something does not work, please read it before reporting.</h3>
+
+<ol>
+<li>
+You can <u>drag'n'drop a node</u> to change parent
+<ul>
+<li>FirstTree accepts only sources from secondTree, secondTree accepts both (for demo purposes)</li>
+<li>You can only drop to folder ("+/-" sign)</li>
+<li>You can't drop an ancestor to any of its descenants</li>
+<li>You can't drop a child to its closest parent</li>
+<li>A node is highlighted if you can drop onto it</li>
+</ul>
+</li>
+
+<li>
+<u>Move nodes up and down, remove them</u> by selecting and pressing tool buttons.
+You surely can't move top nodes higher and bottom nodes lower.
+</li>
+
+<li>
+<u>You can create nodes</u> by clicking create button.
+<ul>
+<li>Currently only simple same nodes are created, but this can be changed easily.</li>
+<li>Nodes are created on top for convinience.</li>
+</ul>
+</li>
+
+<li>All editing operations use <u>server requests(ajax)</u>
+<ul>
+
+<li>Empty folders get loaded dynamically.</li>
+<li>In this demo "test" node can be expanded infinitely (from server).</li>
+<li>Remote communication process is indicated.</li>
+</ul>
+</li>
+
+<li>FirstTree has <u>context menu</u> (right-click on node), attached using events.
+Its main functionality inherits dojo.widget.PopupMenu2.</li>
+
+<li>
+A bunch of <u>events</u> is fired by both tree and controller to simplify integration.
+</li>
+
+
+
+<li>
+<b>Yes, it is OpenSource, and yes, you are free to use &amp; contribute to it.</b>
+</li>
+
+</ol>
+
+<p align="right">Ilia Kantor, ilia at manual dot ru</p>
+
+<hr>
+
+
+
+</body>
+</html>
\ No newline at end of file

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Fisheye.html
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Fisheye.html?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Fisheye.html (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Fisheye.html Thu Apr 13 16:46:55 2006
@@ -0,0 +1,107 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+
+<title>FisheyeList Widget Demo</title>
+
+<script type="text/javascript">
+	var djConfig = {isDebug: true, debugAtAllCosts: false};
+</script>
+<script type="text/javascript" src="../../dojo.js"></script>
+<script language="JavaScript" type="text/javascript">
+	dojo.require("dojo.widget.FisheyeList");
+	dojo.hostenv.writeIncludes();
+</script>
+
+<script>
+	function load_app(id){
+		alert('Icon '+id+' was clicked');
+	}
+</script>
+
+<style>
+
+.dojoHtmlFisheyeListBar {
+	margin: 0 auto;
+	text-align: center;
+}
+
+.outerbar {
+	background-color: #666;
+	text-align: center;
+	position: absolute;
+	left: 0px;
+	top: 0px;
+	width: 100%;
+}
+
+body {
+	font-family: Arial, Helvetica, sans-serif;
+	padding: 0;
+	margin: 0;
+}
+
+.page {
+	padding: 60px 20px 20px 20px;
+}
+
+</style>
+</head>
+<body>
+
+<div class="outerbar">
+
+<div class="dojo-FisheyeList"
+	dojo:itemWidth="50" dojo:itemHeight="50"
+	dojo:itemMaxWidth="200" dojo:itemMaxHeight="200"
+	dojo:orientation="horizontal"
+	dojo:effectUnits="2"
+	dojo:itemPadding="10"
+	dojo:attachEdge="top"
+	dojo:labelEdge="bottom"
+	dojo:enableCrappySvgSupport="false"
+>
+
+	<div class="dojo-FisheyeListItem" onClick="load_app(1);" 
+		dojo:iconsrc="images/icon_browser.png" caption="Web Browser">
+	</div>
+
+	<div class="dojo-FisheyeListItem" onClick="load_app(2);"
+		dojo:iconsrc="images/icon_calendar.png" caption="Calendar">
+	</div>
+
+	<div class="dojo-FisheyeListItem" onClick="load_app(3);"
+		dojo:iconsrc="images/icon_email.png" caption="Email">
+	</div>
+
+	<div class="dojo-FisheyeListItem" onClick="load_app(4);"
+		dojo:iconsrc="images/icon_texteditor.png" caption="Text Editor">
+	</div>
+
+	<div class="dojo-FisheyeListItem" onClick="load_app(5);"
+		dojo:iconsrc="images/icon_update.png" caption="Software Update">
+	</div>
+
+	<div class="dojo-FisheyeListItem" onClick="load_app(6);"
+		dojo:iconsrc="images/icon_users.png" dojo:caption="Users" >
+	</div>
+</div>
+
+</div>
+
+<div class="page">
+
+<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam facilisis enim. Pellentesque in elit et lacus euismod dignissim. Aliquam dolor pede, convallis eget, dictum a, blandit ac, urna. Pellentesque sed nunc ut justo volutpat egestas. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. In erat. Suspendisse potenti. Fusce faucibus nibh sed nisi. Phasellus faucibus, dui a cursus dapibus, mauris nulla euismod velit, a lobortis turpis arcu vel dui. Pellentesque fermentum ultrices pede. Donec auctor lectus eu arcu. Curabitur non orci eget est porta gravida. Aliquam pretium orci id nisi. Duis faucibus, mi non adipiscing venenatis, erat urna aliquet elit, eu fringilla lacus tellus quis erat. Nam tempus ornare lorem. Nullam feugiat.</p>
+
+<p>Sed congue. Aenean blandit sollicitudin mi. Maecenas pellentesque. Vivamus ac urna. Nunc consequat nisi vitae quam. Suspendisse sed nunc. Proin suscipit porta magna. Duis accumsan nunc in velit. Nam et nibh. Nulla facilisi. Cras venenatis urna et magna. Aenean magna mauris, bibendum sit amet, semper quis, aliquet nec, sapien. Aliquam aliquam odio quis erat. Etiam est nisi, condimentum non, lacinia ac, vehicula laoreet, elit. Sed interdum augue sit amet quam dapibus semper. Nulla facilisi. Pellentesque lobortis erat nec quam.</p>
+
+<p>Sed arcu magna, molestie at, fringilla in, sodales eu, elit. Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat augue. Integer fermentum odio lobortis odio. Nullam mollis nisl non metus. Maecenas nec nunc eget pede ultrices blandit. Ut non purus ut elit convallis eleifend. Fusce tincidunt, justo quis tempus euismod, magna nulla viverra libero, sit amet lacinia odio diam id risus. Ut varius viverra turpis. Morbi urna elit, imperdiet eu, porta ac, pharetra sed, nisi. Etiam ante libero, ultrices ac, faucibus ac, cursus sodales, nisl. Praesent nisl sem, fermentum eu, consequat quis, varius interdum, nulla. Donec neque tortor, sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean ut eros sit amet ante pharetra interdum.</p>
+
+<p>Fusce rutrum pede eget quam. Praesent purus. Aenean at elit in sem volutpat facilisis. Nunc est augue, commodo at, pretium a, fermentum at, quam. Nam sit amet enim. Suspendisse potenti. Cras hendrerit rhoncus justo. Integer libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam erat volutpat. Sed adipiscing mi vel ipsum.</p>
+
+<p>Sed aliquam, quam consectetuer condimentum bibendum, neque libero commodo metus, non consectetuer magna risus vitae eros. Pellentesque mollis augue id libero. Morbi nonummy hendrerit dui. Morbi nisi felis, fringilla ac, euismod vitae, dictum mollis, pede. Integer suscipit, est sed posuere ullamcorper, ipsum lectus interdum nunc, quis blandit erat eros hendrerit pede. Vestibulum varius, elit id mattis mattis, nulla est feugiat ante, eget vestibulum augue eros ut odio. Maecenas euismod purus quis felis. Ut hendrerit tincidunt est. Fusce euismod, nunc eu tempus tempor, purus ligula volutpat tellus, nec lacinia sapien enim id risus. Aliquam orci turpis, condimentum sed, sollicitudin vel, placerat in, purus. Proin tortor nisl, blandit quis, imperdiet quis, scelerisque at, nisl. Maecenas suscipit fringilla erat. Curabitur consequat, dui blandit suscipit dictum, felis lectus imperdiet tellus, sit amet ornare risus mauris non ipsum. Fusce a purus. Vestibulum sodales. Sed porta ul
 trices nibh. Vestibulum metus.</p>
+
+</div>
+
+</body>
+</html>

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail.html
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail.html?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail.html (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail.html Thu Apr 13 16:46:55 2006
@@ -0,0 +1,132 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<title>Mail</title>
+
+<script type="text/javascript">
+	var djConfig = {isDebug: true};
+	//djConfig.debugAtAllCosts = true;
+</script>
+<script type="text/javascript" src="../../dojo.js"></script>
+<script language="JavaScript" type="text/javascript">
+	dojo.require("dojo.widget.LayoutPane");
+	dojo.require("dojo.widget.FloatingPane");
+	dojo.require("dojo.widget.ContentPane");
+	dojo.require("dojo.widget.SplitPane");
+	dojo.require("dojo.widget.ColorPalette");
+	dojo.require("dojo.widget.DatePicker");	
+	dojo.require("dojo.widget.Tree");
+	dojo.require("dojo.widget.Checkbox");
+	dojo.require("dojo.widget.TabPane");
+	dojo.require("dojo.widget.Button2");
+	dojo.require("dojo.widget.ResizeHandle");
+	dojo.hostenv.writeIncludes();
+</script>
+
+<link rel=stylesheet href="Mail/mail.css" type="text/css">
+
+<script type="text/javascript" src="Mail/mail.js"></script>
+
+</head>
+<body>
+<div dojoType="LayoutPane"
+	layoutChildPriority='top-bottom'
+	id="main"
+>
+	<div id="topMenu" dojoType="ContentPane" layoutAlign="top" class="header"
+	 style="padding-bottom: 5px;">
+		<div style="float: left; margin-right: 10px;">
+			<button dojoType="Button2" onclick="alert('pretending to download new mail');">
+				<img src="Mail/mail_get.gif" height=18>
+				Get Mail
+			</button>
+		</div>
+		<div style="float: left;">
+			<button dojoType="Button2" onclick='open("Mail/NewMessage.html",null,"height=500,width=600,status=yes,toolbar=no,menubar=no,location=no");'>
+				<img src="Mail/mail_new.gif" height=18>
+				New Message
+			</button>
+		</div>
+		<div style="float: right;">
+			<button dojoType="Button2" onclick="dojo.widget.getWidgetById('options').restoreWindow()">
+				<img src="Mail/checkmark.gif" height=18>
+				Options
+			</button>
+		</div>
+		<div align=center>My mailbox</div>
+		
+	</div>
+
+	<div dojoType="SplitPane"
+		orientation="horizontal"
+		sizerWidth="5"
+		activeSizing="0"
+		layoutAlign="client"
+	>
+		<div id="treePane" dojoType="Tree" toggle="fade" layoutAlign="flood" publishSelectionTopic="listSelected"
+			sizeMin="20" sizeShare="15">
+			<div dojoType="TreeNode" title="Mail Account" childIconSrc="Mail/mailbox1.gif">
+				<div dojoType="TreeNode" title="Inbox"  childIconSrc="Mail/folder_inbox.gif"></div>
+				<div dojoType="TreeNode" title="Sent Mail" childIconSrc="Mail/folder_sent_mail.gif"></div>
+				<div dojoType="TreeNode" title="Deleted"  childIconSrc="Mail/trashcan_full.gif"></div>
+				<div dojoType="TreeNode" title="Saved Mail" childIconSrc="Mail/folder_documents.gif">
+					<div dojoType="TreeNode" title="Friends" childIconSrc="Mail/folder_documents.gif">
+						<div dojoType="TreeNode" title="Bob" childIconSrc="Mail/folder_documents.gif"></div>
+						<div dojoType="TreeNode" title="Jack" childIconSrc="Mail/folder_documents.gif"></div>
+					</div>
+					<div dojoType="TreeNode" title="Work" childIconSrc="Mail/folder_documents.gif"></div>
+				</div>
+			</div>
+		</div>
+
+		<div dojoType="SplitPane"
+			orientation="vertical"
+			sizerWidth="5"
+			activeSizing="0"
+			style="width: 100%; height: 100%;"
+			sizeMin="50" sizeShare="85"
+		>
+			<div id="listPane" dojoType="SplitPanePanel" sizeMin="20" sizeShare="30">
+			</div>
+			<div id="contentPane" dojoType="ContentPane" sizeMin="20" sizeShare="70" href="Mail/MailAccount.html">
+			</div>
+		</div>
+</div>
+
+<div id="options" dojoType="FloatingPane" title="Options"
+	style="width: 300px; height: 200px; left: 300px; top: 300px;"
+	hasShadow="true" resizable="true" titleBarDisplay="simple" windowState="minimized"
+	contentWrapper="layout">
+  <div dojoType="TabPane" layoutAlign="client">
+  	<div dojoType="Tab" label="Sending/Receiving">
+  		Transport type
+  		<select>
+  			<option>POP3</option>
+  			<option>IMAP</option>
+  		</select>
+  		<br>
+  		Server: <input type="text"></input>
+  	</div>
+  	<div dojoType="Tab" label="Composition">
+		<input type="checkbox" name="cb1" id="cb1" dojoType="Checkbox" /> <label for="cb1">hello world</label><br />
+		<input type="checkbox" name="cb2" id="cb2" dojoType="Checkbox" /> <label for="cb2">foo bar baz</label><br />
+		<input type="checkbox" name="cb3" id="cb3" dojoType="Checkbox" /> <label for="cb3">woo yay hoopla</label><br /> 	
+  	</div>
+  </div>
+  <div dojoType="LayoutPane" layoutAlign="bottom" style="height: 25px; padding-top: 5px;">
+  	<div class="box">
+		<button dojoType="Button2" onclick="dojo.widget.getWidgetById('options').hide();">
+			<img src="Mail/cancel.gif" height=18>
+			Cancel
+		</button>
+		<button dojoType="Button2" onclick="dojo.widget.getWidgetById('options').hide();">
+			<img src="Mail/ok.gif" height=18>
+			OK
+		</button>
+		<div style="clear: both;"></div>
+	</div>
+  </div>
+</div>
+
+</body>
+</html>
\ No newline at end of file

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Bob.html
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Bob.html?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Bob.html (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Bob.html Thu Apr 13 16:46:55 2006
@@ -0,0 +1,5 @@
+<table width=100% style="border: 1px;">
+<tr class="header"><td>Sender</td><td>Subject</td><td>Date</td></tr>
+<tr><td>Adam Arlen</td><td>meeting notes</td><td>2005-12-19</td></tr>
+<tr><td>Bob Baxter</td><td>schedule</td><td>2005-12-18</td></tr>
+</table>
\ No newline at end of file

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Deleted.html
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Deleted.html?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Deleted.html (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Deleted.html Thu Apr 13 16:46:55 2006
@@ -0,0 +1,6 @@
+<table width=100% style="border: 1px;">
+<tr class="header"><td>Sender</td><td>Subject</td><td>Date</td></tr>
+<tr><td>Adam Arlen</td><td>yesterday's meeting</td><td>2005-12-19</td></tr>
+<tr><td>Bob Baxter</td><td>finished work</td><td>2005-12-18</td></tr>
+<tr><td>Carrey Crown</td><td>breakfast</td><td>2005-12-17</td></tr>
+</table>
\ No newline at end of file

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Friends.html
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Friends.html?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Friends.html (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Friends.html Thu Apr 13 16:46:55 2006
@@ -0,0 +1,5 @@
+<table width=100% style="border: 1px;">
+<tr class="header"><td>Sender</td><td>Subject</td><td>Date</td></tr>
+<tr><td>Adam Arlen</td><td>meeting notes</td><td>2005-12-19</td></tr>
+<tr><td>Bob Baxter</td><td>schedule</td><td>2005-12-18</td></tr>
+</table>
\ No newline at end of file

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Inbox.html
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Inbox.html?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Inbox.html (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Inbox.html Thu Apr 13 16:46:55 2006
@@ -0,0 +1,7 @@
+<table width=100% style="border: 1px;">
+<tr class="header"><td>Sender</td><td>Subject</td><td>Date</td></tr>
+<tr onClick='displayMessage("Meeting");'><td>Adam Arlen</td><td>today's meeting</td><td>2005-12-19</td></tr>
+<tr onClick='displayMessage("RemainingWork");'><td>Bob Baxter</td><td>remaining work</td><td>2005-12-18</td></tr>
+<tr onClick='displayMessage("Lunch");'><td>Carrey Crown</td><td>lunch</td><td>2005-12-17</td></tr>
+<tr onClick='displayMessage("Paint");'><td>David Davis</td><td>paint</td><td>2005-12-16</td></tr>
+</table>
\ No newline at end of file

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Jack.html
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Jack.html?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Jack.html (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Jack.html Thu Apr 13 16:46:55 2006
@@ -0,0 +1,5 @@
+<table width=100% style="border: 1px;">
+<tr class="header"><td>Sender</td><td>Subject</td><td>Date</td></tr>
+<tr><td>Adam Arlen</td><td>meeting notes</td><td>2005-12-19</td></tr>
+<tr><td>Bob Baxter</td><td>schedule</td><td>2005-12-18</td></tr>
+</table>
\ No newline at end of file

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Lunch.html
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Lunch.html?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Lunch.html (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Lunch.html Thu Apr 13 16:46:55 2006
@@ -0,0 +1,6 @@
+<div class="subject">
+<span class="header">Subject:</span> lunch
+</div>
+<br>
+<p>where should we go for lunch?</p>
+

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/MailAccount.html
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/MailAccount.html?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/MailAccount.html (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/MailAccount.html Thu Apr 13 16:46:55 2006
@@ -0,0 +1,16 @@
+This is a simple application mockup showing some of the dojo widgets:
+<ul>
+  <li>split pane</li>
+  <li>floating pane</li>
+  <li>layout pane</li>
+  <li>tree</li>
+  <li>button</li>
+  <li>TabPane</li>
+  <li>editor</li>
+</ul>
+Click on the messages in the Inbox, or try to edit the options or create a new message.
+There's no server running, so the app is just a facade and it doesn't really do anything.
+
+<p>
+-- Bill
+</p>
\ No newline at end of file

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Meeting.html
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Meeting.html?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Meeting.html (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Meeting.html Thu Apr 13 16:46:55 2006
@@ -0,0 +1,6 @@
+<div class="subject">
+<span class="header">Subject:</span> today's meeting
+</div>
+<br>
+<p>Cancelling the meeting today.  Sally is sick and Bob is busy.</p>
+

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/NewMessage.html
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/NewMessage.html?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/NewMessage.html (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/NewMessage.html Thu Apr 13 16:46:55 2006
@@ -0,0 +1,84 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<title>New Message</title>
+
+<script type="text/javascript">
+	var djConfig = {isDebug: true};
+	//djConfig.debugAtAllCosts = true;
+</script>
+<script type="text/javascript" src="../../../dojo.js"></script>
+<script language="JavaScript" type="text/javascript">
+	dojo.require("dojo.widget.Editor");	
+	dojo.require("dojo.widget.ComboBox");
+	dojo.require("dojo.widget.LayoutPane");
+	dojo.require("dojo.widget.Button2");
+	dojo.hostenv.writeIncludes();
+</script>
+<link rel=stylesheet href="mail.css" type="text/css">
+
+<script>
+   	function onLoad(){
+   		// this is just to workaround a bug on firefox
+   		dojo.widget.getWidgetById("cancel").onResized();
+   		dojo.widget.getWidgetById("ok").onResized();
+   	}
+   	dojo.addOnLoad(onLoad);
+</script>
+</head>
+<body>
+<div dojoType="LayoutPane" id="main">
+
+<div dojoType="LayoutPane" layoutAlign="top" style="overflow: visible; z-index: 10;">
+	<table width=100%>
+		<tr>
+			<td style="padding-right: 20px;">To:</td>
+			<td width=100%>
+				<select dojoType="combobox" style="width: 100%;">
+					<option>adam@yahoo.com</option>
+					<option>barry@yahoo.com</option>
+					<option>bob@yahoo.com</option>
+					<option>cal@yahoo.com</option>
+					<option>chris@yahoo.com</option>
+					<option>courtney@yahoo.com</option>
+				</select>
+			</td>
+		</tr>
+		<tr>
+			<td style="padding-right: 20px;">Subject:</td>
+			<td width=100%>
+				<select dojoType="combobox" style="width: 100%;">
+					<option>progress meeting</option>
+					<option>reports</option>
+					<option>lunch</option>
+					<option>vacation</option>
+					<option>status meeting</option>
+				</select>
+			</td>
+		</tr>
+	</table>
+</div>
+
+<div dojoType="LayoutPane" layoutAlign="client">
+	<div id="editable" dojoType="Editor" widgetId="editdiv" items="formatblock;|;insertunorderedlist;insertorderedlist;|;bold;italic;underline;strikethrough;|;createLink;">
+		Type the address above (try an address starting with a,b,c,d, to test autocompletion,
+		and then type your message here...
+		<br><br><br><br><br><br><br><br><br><br>
+	</div>
+</div>
+
+<div dojoType="LayoutPane" layoutAlign="bottom">
+	<div layoutAlign="right" class="box">
+		<button id="cancel" dojoType="Button2" onclick="close();">
+			<img src="cancel.gif" height=18>
+			Cancel
+		</button>
+		<button id="ok" dojoType="Button2" onclick="close();">
+			<img src="ok.gif" height=18>
+			OK
+		</button>
+	</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Paint.html
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Paint.html?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Paint.html (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Paint.html Thu Apr 13 16:46:55 2006
@@ -0,0 +1,8 @@
+<div class="subject">
+<span class="header">Subject:</span> paint
+</div>
+<br>
+<p>what color is good for the new office?</p>
+<div dojoType="ColorPalette"></div>
+<p>Let me know soon</p>
+

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/RemainingWork.html
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/RemainingWork.html?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/RemainingWork.html (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/RemainingWork.html Thu Apr 13 16:46:55 2006
@@ -0,0 +1,8 @@
+<div class="subject">
+<span class="header">Subject:</span> remaining work
+</div>
+<br>
+<p>Hey, we need to talk about whose gonna do all the leftover work.
+Pick a day you want to meet:
+<div dojoType="datepicker"></div>
+</p>

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/SavedMail.html
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/SavedMail.html?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/SavedMail.html (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/SavedMail.html Thu Apr 13 16:46:55 2006
@@ -0,0 +1,5 @@
+<table width=100% style="border: 1px;">
+<tr class="header"><td>Sender</td><td>Subject</td><td>Date</td></tr>
+<tr><td>Adam Arlen</td><td>meeting notes</td><td>2005-12-19</td></tr>
+<tr><td>Bob Baxter</td><td>schedule</td><td>2005-12-18</td></tr>
+</table>
\ No newline at end of file

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/SentMail.html
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/SentMail.html?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/SentMail.html (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/SentMail.html Thu Apr 13 16:46:55 2006
@@ -0,0 +1,7 @@
+<table width=100% style="border: 1px;">
+<tr class="header"><td>To</td><td>Subject</td><td>Date</td></tr>
+<tr><td>Jim Jones</td><td>today's meeting</td><td>2005-12-19</td></tr>
+<tr><td>Fred Fishcher</td><td>remaining work</td><td>2005-12-18</td></tr>
+<tr><td>Rob Raymond</td><td>lunch</td><td>2005-12-17</td></tr>
+<tr><td>Sandy Stellar</td><td>health plan</td><td>2005-12-16</td></tr>
+</table>
\ No newline at end of file

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Work.html
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Work.html?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Work.html (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/Work.html Thu Apr 13 16:46:55 2006
@@ -0,0 +1,5 @@
+<table width=100% style="border: 1px;">
+<tr class="header"><td>Sender</td><td>Subject</td><td>Date</td></tr>
+<tr><td>Adam Arlen</td><td>meeting notes</td><td>2005-12-19</td></tr>
+<tr><td>Bob Baxter</td><td>schedule</td><td>2005-12-18</td></tr>
+</table>
\ No newline at end of file

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/cancel.gif
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/cancel.gif?rev=393978&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/cancel.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/checkmark.gif
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/checkmark.gif?rev=393978&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/checkmark.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/folder_documents.gif
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/folder_documents.gif?rev=393978&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/folder_documents.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/folder_inbox.gif
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/folder_inbox.gif?rev=393978&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/folder_inbox.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/folder_sent_mail.gif
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/folder_sent_mail.gif?rev=393978&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/demos/widget/Mail/folder_sent_mail.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org