You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by we...@apache.org on 2010/05/17 09:14:02 UTC

svn commit: r944995 [1/2] - in /myfaces/core/trunk/api/src: assembler/ main/javascript/META-INF/resources/myfaces/_impl/_util/ main/javascript/META-INF/resources/myfaces/_impl/core/ main/javascript/META-INF/resources/myfaces/_impl/xhrCore/ main/javascr...

Author: werpu
Date: Mon May 17 07:14:01 2010
New Revision: 944995

URL: http://svn.apache.org/viewvc?rev=944995&view=rev
Log:
https://issues.apache.org/jira/browse/MYFACES-2721

PPS Part partially cleaned up, Queue part entirely cleaned up
and now uses inheritance like it should, also added
a speed optimized queue

xhr part still needs serious cleanup.

Added:
    myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Queue.js
    myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/Impl.js
Modified:
    myfaces/core/trunk/api/src/assembler/jsfscripts-compiler.xml
    myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Dom.js
    myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Lang.js
    myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_ListenerQueue.js
    myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_UnitTest.js
    myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/_Runtime.js
    myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxRequest.js
    myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxRequestQueue.js
    myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxResponse.js
    myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxUtils.js
    myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_Exception.js
    myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_xhrCoreAdapter.js
    myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/api/readme.txt

Modified: myfaces/core/trunk/api/src/assembler/jsfscripts-compiler.xml
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/assembler/jsfscripts-compiler.xml?rev=944995&r1=944994&r2=944995&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/assembler/jsfscripts-compiler.xml (original)
+++ myfaces/core/trunk/api/src/assembler/jsfscripts-compiler.xml Mon May 17 07:14:01 2010
@@ -27,6 +27,7 @@
             <includes>
                 <include>**/_impl/core/_Runtime.js</include>
                 <include>**/_impl/_util/_Lang.js</include>
+                <include>**/_impl/_util/_Queue.js</include>
                 <include>**/_impl/_util/_ListenerQueue.js</include>
                 <include>**/_impl/_util/_Dom.js</include>
                 <include>**/_impl/_util/_HtmlStripper.js</include>
@@ -36,7 +37,7 @@
                 <include>**/_impl/xhrCore/_AjaxRequest.js</include>
                 <include>**/_impl/xhrCore/_AjaxResponse.js</include>
                 <include>**/_impl/xhrCore/_xhrCoreAdapter.js</include>
-                <include>**/_impl/core/jsf_impl.js</include>
+                <include>**/_impl/core/Impl.js</include>
                 <include>**/api/jsf.js</include>
             </includes>
         </script>

Modified: myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Dom.js
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Dom.js?rev=944995&r1=944994&r2=944995&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Dom.js (original)
+++ myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Dom.js Mon May 17 07:14:01 2010
@@ -66,7 +66,9 @@ myfaces._impl.core._Runtime.singletonExt
                         && item.getAttribute('src') != null
                         && item.getAttribute('src').length > 0) {
                     // external script auto eval
-                    myfaces._impl.core._Runtime.loadScript(item.getAttribute('src'), item.getAttribute('type'), false, "ISO-8859-1");
+                    //TODO fix the encoding here, we have to assume the src is the same encoding as the document
+                    //or enforce auto
+                    myfaces._impl.core._Runtime.loadScript(item.getAttribute('src'), item.getAttribute('type'), false, "UTF-8");
                 } else {
                     // embedded script auto eval
                     var test = item.text;
@@ -91,23 +93,29 @@ myfaces._impl.core._Runtime.singletonExt
                 }
             }
         });
-
-        var scriptElements = this.findByTagName(item, "script", true);
-        if (scriptElements == null) return;
-        for (var cnt = 0; cnt < scriptElements.length; cnt++) {
-            executeScriptTag(scriptElements[cnt]);
+        try {
+            var scriptElements = this.findByTagName(item, "script", true);
+            if (scriptElements == null) return;
+            for (var cnt = 0; cnt < scriptElements.length; cnt++) {
+                executeScriptTag(scriptElements[cnt]);
+            }
+        } finally {
+            //the usual ie6 fix code
+            //the IE6 garbage collector is broken
+            //nulling closures helps somewhat to reduce
+            //mem leaks, which are impossible to avoid
+            //at this browser
+            executeScriptTag = null;
         }
     },
 
     /**
      * Simple delete on an existing item
      */
-    deleteItem: function(request, context, itemIdToReplace) {
-        var item = document.getElementById(itemIdToReplace);
+    deleteItem: function(itemIdToReplace) {
+        var item = this.byId(itemIdToReplace);
         if (item == null) {
-            myfaces._impl._util._Lang.throwNewWarning
-                    (request, context, "Utils", "deleteItem", "Unknown Html-Component-ID: " + itemIdToReplace);
-            return;
+            throw Error("_Dom.deleteItem  Unknown Html-Component-ID: " + itemIdToReplace);
         }
 
         item.parentNode.removeChild(item);
@@ -195,6 +203,10 @@ myfaces._impl.core._Runtime.singletonExt
      */
     findById : function(fragment, itemId) {
 
+        if(fragment === document) {
+            return document.getElementById(itemId);
+        }
+
         if (fragment.nodeType == 1 && fragment.querySelector) {
             //we can use the query selector here
             if (fragment.id && fragment.id === itemId) return fragment;
@@ -204,7 +216,12 @@ myfaces._impl.core._Runtime.singletonExt
         var filter = function(node) {
             return 'undefined' != typeof node.id && node.id === itemId;
         };
-        return this.findFirst(fragment, filter);
+        try {
+            return this.findFirst(fragment, filter);
+        } finally {
+            //ie6 fix code
+            filter = null;
+        }
     },
 
     /**
@@ -300,19 +317,25 @@ myfaces._impl.core._Runtime.singletonExt
         var filter = function(node) {
             return _Lang.exists(node, "tagName") && _Lang.equalsIgnoreCase(node.tagName, tagName);
         };
+        try {
 
-        //html 5 selector
-        if (deepScan && fragment.querySelectorAll) {
-            var result = fragment.querySelectorAll(tagName);
-            if (fragment.nodeType == 1 && filter(fragment)) {
-                result = (result == null) ? [] : _Lang.objToArray(result);
-                result.push(fragment);
-            }
-            return result;
-        }
-        //if we are not in a html 5 environment which supports node selectors
-        //we use the usual recursive fallback.
-        return this.findAll(fragment, filter, deepScan);
+            //html 5 selector
+            if (deepScan && fragment.querySelectorAll) {
+                var result = fragment.querySelectorAll(tagName);
+                if (fragment.nodeType == 1 && filter(fragment)) {
+                    result = (result == null) ? [] : _Lang.objToArray(result);
+                    result.push(fragment);
+                }
+                return result;
+            }
+            //if we are not in a html 5 environment which supports node selectors
+            //we use the usual recursive fallback.
+            return this.findAll(fragment, filter, deepScan);
+        } finally {
+            //the usual IE6 is broken, fix code
+            filter = null;
+            _Lang = null;
+        }
 
     },
 
@@ -321,21 +344,28 @@ myfaces._impl.core._Runtime.singletonExt
         var filter = function(node) {
             return  _Lang.exists(node, "name") && _Lang.equalsIgnoreCase(node.name, name);
         };
-        if ('undefined' == typeof deepScan) {
-            deepScan = false;
-        }
+        try {
+            if ('undefined' == typeof deepScan) {
+                deepScan = false;
+            }
 
-        if (deepScan && fragment.querySelectorAll) {
-            var result = fragment.querySelectorAll("[name=" + name + "]");
-            if (fragment.nodeType == 1 && filter(fragment)) {
-                result = (result == null) ? [] : _Lang.objToArray(result);
-                result.push(fragment);
+            if (deepScan && fragment.querySelectorAll) {
+                var result = fragment.querySelectorAll("[name=" + name + "]");
+                if (fragment.nodeType == 1 && filter(fragment)) {
+                    result = (result == null) ? [] : _Lang.objToArray(result);
+                    result.push(fragment);
+                }
+                return result;
             }
-            return result;
-        }
 
-        return this.findAll(fragment, filter, deepScan);
-    },
+            return this.findAll(fragment, filter, deepScan);
+        } finally {
+            //the usual IE6 is broken, fix code
+            filter = null;
+            _Lang = null;
+        }
+    }
+    ,
 
     /**
      * finds the elements by an attached style class
@@ -357,28 +387,41 @@ myfaces._impl.core._Runtime.singletonExt
             }
             return false;
         });
+        try {
+            if ('undefined' == typeof deepScan) {
+                deepScan = false;
+            }
 
-        if ('undefined' == typeof deepScan) {
-            deepScan = false;
-        }
+            //html5 getElementsByClassname
+            if (fragment.getElementsByClassName && deepScan) {
+                return fragment.getElementsByClassName(styleClass);
+            }
+            //html5 speed optimization for browsers which do not ,
+            //have the getElementsByClassName implemented
+            //but only for deep scan and normal parent nodes
+            else if (fragment.querySelectorAll && deepScan) {
+                var selector = "." + styleClass;
+                var result = fragment.querySelectorAll(selector);
+
+                if (fragment.nodeType == 1 && filter(fragment)) {
+                    result = (result == null) ? [] : result;
+                    result = _Lang.objToArrayl(result);
+                    result.push(fragment);
+                }
+                return result;
+            } else {
+                //fallback to the classical filter methods if we cannot use the
+                //html 5 selectors for whatever reason
+                return this.findAll(fragment, filter, deepScan);
+            }
 
-        //html5 speed optimization, but only for deep scan and normal parent nodes
-        if (fragment.querySelectorAll && deepScan) {
-            var selector = "." + styleClass;
-            var result = fragment.querySelectorAll(selector);
-
-            if (fragment.nodeType == 1 && filter(fragment)) {
-                result = (result == null) ? [] : result;
-                result = _Lang.objToArrayl(result);
-                result.push(fragment);
-            }
-            return result;
-        }
-
-        //fallback to the classical filter methods if we cannot use the
-        //html 5 selectors for whatever reason
-        return this.findAll(fragment, filter, deepScan);
-    },
+        } finally {
+            //the usual IE6 is broken, fix code
+            filter = null;
+            _Lang = null;
+        }
+    }
+    ,
 
     /**
      * a filtered findAll for subdom treewalking
@@ -398,7 +441,8 @@ myfaces._impl.core._Runtime.singletonExt
             return this._recursionBasedSearchAll(rootNode, filter, deepScan);
         }
 
-    },
+    }
+    ,
 
     /**
      * classical recursive way which definitely will work on all browsers
@@ -435,7 +479,8 @@ myfaces._impl.core._Runtime.singletonExt
             retVal = retVal.concat(subRetVals);
         }
         return retVal;
-    },
+    }
+    ,
 
     /**
      * the faster dom iterator based search, works on all newer browsers
@@ -474,7 +519,8 @@ myfaces._impl.core._Runtime.singletonExt
         var treeWalker = document.createTreeWalker(rootNode, NodeFilter.SHOW_ELEMENT, treeWalkerfilter, false);
         while (treeWalker.nextNode());
         return retVal;
-    },
+    }
+    ,
 
     /**
      *
@@ -487,11 +533,12 @@ myfaces._impl.core._Runtime.singletonExt
     findFormElement : function(form, nameOrIdenitifier) {
         var eLen = form.elements.length;
         //TODO add iterator handlers here for browsers which allow dom filters and iterators
+        var _RT = myfaces._impl._util._Runtime;
 
         for (var e = 0; e < eLen; e++) {
             var elem = form.elements[e];
-            if ('undefined' != typeof elem.name && elem.name === nameOrIdenitifier) return elem;
-            if ('undefined' != typeof elem.id && elem.id === nameOrIdenitifier) return elem;
+            if (_RT.exists(elem,"name") && elem.name === nameOrIdenitifier) return elem;
+            if (_RT.exists(elem,"id") && elem.id === nameOrIdenitifier) return elem;
         } // end of for (formElements)
         return null;
     }
@@ -579,8 +626,7 @@ myfaces._impl.core._Runtime.singletonExt
      * the same id but are located in different forms -> MyFaces 1.1.4 two forms ->
      * 2 inputHidden fields with ID jsf_tree_64 & jsf_state_64 ->
      * http://www.arcknowledge.com/gmane.comp.jakarta.myfaces.devel/2005-09/msg01269.html
-     * @param {Object} request
-     * @param {Object} context (Map)
+     *
      * @param {String} itemIdOrName - ID of the HTML element located inside the form
      * @param {Node} form - form element containing the element
      * @param {boolean} nameSearch if set to true a search for name is also done
@@ -588,43 +634,36 @@ myfaces._impl.core._Runtime.singletonExt
      * @return {Object}   the element if found else null
      *
      */
-    getElementFromForm : function(request, context, itemIdOrName, form, nameSearch, localSearchOnly) {
+    getElementFromForm : function(itemIdOrName, form, nameSearch, localSearchOnly) {
         var _Lang = myfaces._impl._util._Lang;
-        try {
 
-            if ('undefined' == typeof form || form == null) {
-                return document.getElementById(itemIdOrName);
-            }
-            if ('undefined' == typeof nameSearch || nameSearch == null) {
-                nameSearch = false;
-            }
-            if ('undefined' == typeof localSearchOnly || localSearchOnly == null) {
-                localSearchOnly = false;
-            }
+        if ('undefined' == typeof form || form == null) {
+            return this.findById(document, itemIdOrName);
+        }
 
-            var fLen = form.elements.length;
 
-            //we first check for a name entry!
+        var isNameSearch = ('undefined' == typeof nameSearch || nameSearch == null)? false: nameSearch;
+        var isLocalSearchOnly = ('undefined' == typeof localSearchOnly || localSearchOnly == null)? false: localSearchOnly;
 
-            //'undefined' != typeof form.elements[itemIdOrName] && null != form.elements[itemIdOrName]
-            if (nameSearch && _Lang.exists(form, "elements." + itemIdOrName)) {
-                return form.elements[itemIdOrName];
-            }
-            //if no name entry is found we check for an Id
-            for (var f = 0; f < fLen; f++) {
-                var element = form.elements[f];
-                if (_Lang.exists(element, "id") && element.id == itemIdOrName) {
-                    return element;
-                }
-            }
-            // element not found inside the form -> try document.getElementById
-            // (kann be null if element doesn't exist)
-            if (!localSearchOnly) {
-                return document.getElementById(itemIdOrName);
-            }
-        } catch (e) {
-            _Lang.throwNewError(request, context, "Utils", "getElementFromForm", e);
+
+        var fLen = form.elements.length;
+
+        //we first check for a name entry!
+        if (isNameSearch && _Lang.exists(form, "elements." + itemIdOrName)) {
+            return form.elements[itemIdOrName];
+        }
+        //if no name entry is found we check for an Id
+        var element = this.findById(form, itemIdOrName);
+        if(element != null)  {
+            return element;
         }
+
+        // element not found inside the form -> try document.getElementById
+        // (kann be null if element doesn't exist)
+        if (!isLocalSearchOnly) {
+            return this.findById(document, itemIdOrName);
+        }
+
         return null;
     }
     ,
@@ -724,7 +763,6 @@ myfaces._impl.core._Runtime.singletonExt
     ,
 
     /**
-     * [STATIC]
      * gets a parent of an item with a given tagname
      * @param {Node} item - child element
      * @param {String} tagNameToSearchFor - TagName of parent element
@@ -744,6 +782,7 @@ myfaces._impl.core._Runtime.singletonExt
         return this.getFilteredParent(item, searchClosure);
     }
     ,
+
     /**
      * A parent walker which uses
      * a filter closure for filtering
@@ -770,7 +809,6 @@ myfaces._impl.core._Runtime.singletonExt
     }
     ,
 
-
     /**
      * a closure based child filtering routine
      * which steps one level down the tree and
@@ -793,7 +831,6 @@ myfaces._impl.core._Runtime.singletonExt
     }
     ,
 
-
     /**
      * gets the child of an item with a given tag name
      * @param {Node} item - parent element
@@ -814,8 +851,6 @@ myfaces._impl.core._Runtime.singletonExt
     }
     ,
 
-
-
     /**
      * cross ported from dojo
      * fetches an attribute from a node

Modified: myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Lang.js
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Lang.js?rev=944995&r1=944994&r2=944995&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Lang.js (original)
+++ myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Lang.js Mon May 17 07:14:01 2010
@@ -457,6 +457,75 @@ myfaces._impl.core._Runtime.singletonExt
 
     },
 
+    //not yet used
+    /**
+     * attaches a standard iterator if
+     * the collection does not have one already
+     * 
+     * @param inColl
+     */
+  /*  attachIterators : function (inColl ) {
+        var _coll = inColl;
+
+        if(_coll instanceof Array) {
+            if(!_coll.each) {
+                _coll.each = function(closure) {
+                    for(var cnt = 0; cnt < _coll.length; cnt++) {
+                        closure(_coll[cnt]);
+                    }
+                }
+            }
+            if(!_coll.filter) {
+                _coll.filter = function(closure) {
+                    var retVal = [];
+                    for(var cnt = 0; cnt < _coll.length; cnt++) {
+                        var elem = closure(_coll[cnt]);
+                        if(closure(elem)) {
+                            retVal.push(elem)
+                        }
+                    }
+                }
+            }
+
+        } else {
+            if(!_coll.each) {
+                _coll.each = function(closure) {
+                    for(var key in _coll.length) {
+                        closure(key, _coll[key]);
+                    }
+                }
+            }
+            if(!_coll.filter) {
+                _coll.filter = function(closure) {
+                    var retVal = [];
+                    for(var key in _coll.length) {
+                        var elem = closure(_coll[key]);
+                        if(closure(key, elem)) {
+                            retVal.push(elem)
+                        }
+                    }
+                }
+            }
+
+        }
+    },  */
+
+    /**
+     * helper to automatically apply a delivered arguments map
+     * to its destination which has a field "_"<key>
+     *
+     * @param destination the destination object
+     * @param args the arguments array
+     * @param argNames the argument names to be transferred
+     */
+    applyArguments: function(destination, args, argNames) {
+        for(var cnt = 0; cnt < args.length ; cnt++) {
+            if('undefined' != typeof destination["_"+argNames[cnt]]) {
+                destination["_"+argNames[cnt]] = args[cnt];
+            }
+        }
+    },
+
     logLog: function(/*varargs*/) {
         var argumentStr = this.objToArray(arguments).join(" ");
         if (window.console && window.console.log) {

Modified: myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_ListenerQueue.js
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_ListenerQueue.js?rev=944995&r1=944994&r2=944995&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_ListenerQueue.js (original)
+++ myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_ListenerQueue.js Mon May 17 07:14:01 2010
@@ -12,13 +12,10 @@
  * idea:
  * var queue = new myfaces._impl._util._ListenerQueue();
  */
-myfaces._impl.core._Runtime.extendClass("myfaces._impl._util._ListenerQueue", Object, {
-    constructor_: function() {
-        this._queue = [];
-    },
+myfaces._impl.core._Runtime.extendClass("myfaces._impl._util._ListenerQueue", myfaces._impl._util._Queue, {
 
-    length: function() {
-      return this._queue.length;  
+    constructor_: function() {
+        this._callSuper("constructor");
     },
 
     /**
@@ -37,9 +34,9 @@ myfaces._impl.core._Runtime.extendClass(
      *
      * @param listener the listener to be added
      */
-    add : function(/*function*/listener) {
+    enqueue : function(/*function*/listener) {
         this._assertListener(listener);
-        this._queue.push(listener);
+        this._inherited();
     },
 
     /**
@@ -49,21 +46,9 @@ myfaces._impl.core._Runtime.extendClass(
      */
     remove : function(/*function*/listener) {
         this._assertListener(listener);
-        /*find element in queue*/
-        var cnt = 0;
-        var len = this._queue.length;
-        while (cnt < len && this._queue[cnt] != listener) {
-            cnt += 1;
-        }
-        /*found*/
-        if (cnt < len) {
-            this._queue[cnt] = null;
-            /*we remove the element now as fast as possible*/
-            this._queue.splice(cnt, 1);
-        }
-
+        this._inherited();
     },
-    
+
     /**
      * generic broadcast with a number of arguments being passed down
      * @param scope the execution scope for the event callback
@@ -71,34 +56,25 @@ myfaces._impl.core._Runtime.extendClass(
      *                  down the queue function
      */
     broadcastScopedEvent : function(scope, /*any*/argument) {
-        for (var cnt = 0; cnt < this._queue.length; cnt ++) {
-            /**
-             * we call the original method under its original scope
-             * use hitch to keep the original scope in place
-             * because there is no way that I can keep it from here
-             **/
-            var varArgs = [];
-            var len = arguments.length;
-            for (var argsCnt = 1; argsCnt < len; argsCnt++) {
-                varArgs.push(arguments[argsCnt]);
-            }
-            this._queue[cnt].apply(scope, varArgs);
-        }
+        var _Lang = myfaces._impl._util._Lang;
+        var _args = _Lang.objToArray(arguments);
+
+        var broadCastFunc = function(element) {
+            element.apply(scope, Array.prototype.slice(_args, 1));
+        };
+        this.each(broadCastFunc);
     },
 
     /**
      * generic broadcast with a number of arguments being passed down
      */
     broadcastEvent : function(/*any*/argument) {
-        var len = this._queue.length;
-        for (var cnt = 0; cnt < len; cnt ++) {
-            /**
-             * we call the original method under its original scope
-             * use hitch to keep the original scope in place
-             * because there is no way that I can keep it from here
-             **/
+        var _Lang = myfaces._impl._util._Lang;
+        var _args = _Lang.objToArray(arguments);
 
-            this._queue[cnt].apply(null, arguments);
-        }
+        var broadCastFunc = function(element) {
+            element.apply(null, _args);
+        };
+        this.each(broadCastFunc);
     }
 });
\ No newline at end of file

Added: myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Queue.js
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Queue.js?rev=944995&view=auto
==============================================================================
--- myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Queue.js (added)
+++ myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Queue.js Mon May 17 07:14:01 2010
@@ -0,0 +1,154 @@
+/*
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *  under the License.
+ */
+
+myfaces._impl.core._Runtime.extendClass("myfaces._impl._util._Queue", Object, {
+    //faster queue by http://safalra.com/web-design/javascript/queues/Queue.js
+    //license public domain
+    //The trick is to simply reduce the number of slice and slice ops to a bare minimum.
+
+    _xhrQueue : null,
+    _queueSpace : 0,
+    _queueSize: -1,
+
+    constructor_: function() {
+        this._xhrQueue = [];
+    },
+
+    length: function() {
+        // return the number of elements in the queue
+        return this._xhrQueue.length - this._queueSpace;
+
+    },
+
+    isEmpty: function() {
+        // return true if the queue is empty, and false otherwise
+        return (this._xhrQueue.length == 0);
+    },
+
+    setQueueSize: function(newSize) {
+        this._queueSize = newSize;
+        this._readjust();
+    },
+
+    /**
+     * adds a listener to the queue
+     *
+     * @param element the listener to be added
+     */
+    enqueue : function(/*function*/element) {
+        this._xhrQueue.push(element);
+        //qeuesize is bigger than the limit we drop one element so that we are
+        //back in line
+        this._readjust();
+    },
+
+    _readjust: function() {
+        while (this._queueSize > -1 && this.length() > this._queueSize) {
+            this.dequeue();
+        }
+    },
+
+    /**
+     * removes a listener form the queue
+     *
+     * @param element the listener to be removed
+     */
+    remove : function(/*function*/element) {
+        /*find element in queue*/
+        var index = this.indexOf(element);
+        /*found*/
+        if (index != -1) {
+            this._xhrQueue.splice(index, 1);
+        }
+    },
+
+    dequeue: function() {
+        // initialise the element to return to be undefined
+        var element = null;
+
+        // check whether the queue is empty
+        if (this._xhrQueue.length) {
+
+            // fetch the oldest element in the queue
+            element = this._xhrQueue[this._queueSpace];
+
+            // update the amount of space and check whether a shift should occur
+            //added here a max limit of 30
+            if (++this._queueSpace * 2 >= this._xhrQueue.length || this._queueSpace > 300) {
+
+                // set the queue equal to the non-empty portion of the queue
+                this._xhrQueue = this._xhrQueue.slice(this._queueSpace);
+
+                // reset the amount of space at the front of the queue
+                this._queueSpace = 0;
+
+            }
+
+        }
+
+        // return the removed element
+        return element;
+    },
+
+    /**
+     * simple foreach
+     *
+     * @param closure a closure which processes the element
+     */
+    each: function(closure) {
+        var cnt = this._queueSpace;
+        var len = this._xhrQueue.length;
+        for (; cnt < len; cnt++) {
+            closure(this._xhrQueue[cnt]);
+        }
+    },
+
+    /**
+     * Simple filter
+     *
+     * @param closure a closure which returns true or false depending
+     * whether the filter has triggered
+     *
+     * @return an array of filtered queue entries
+     */
+    filter: function(closure) {
+        var retVal = [];
+        var cnt = this._queueSpace;
+        var len = this._xhrQueue.length;
+        for (; cnt < len; cnt++) {
+            if (closure(this._xhrQueue[cnt])) {
+                retVal.push(this._xhrQueue[cnt]);
+            }
+        }
+        return retVal;
+    },
+
+    indexOf: function(element) {
+        var cnt = this._queueSpace;
+        var len = this._xhrQueue.length;
+        while (cnt < len && this._xhrQueue[cnt] !== element) {
+            cnt += 1;
+        }
+        /*found*/
+        cnt = (cnt < len) ? cnt : -1;
+        return cnt;
+    },
+
+    cleanup: function() {
+        this._xhrQueue = [];
+        this._queueSpace = 0;
+    }
+});
+

Modified: myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_UnitTest.js
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_UnitTest.js?rev=944995&r1=944994&r2=944995&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_UnitTest.js (original)
+++ myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_UnitTest.js Mon May 17 07:14:01 2010
@@ -1,3 +1,19 @@
+/*
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *  under the License.
+ */
+
+
 /**
  * This class is for http based unit tests
  *

Added: myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/Impl.js
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/Impl.js?rev=944995&view=auto
==============================================================================
--- myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/Impl.js (added)
+++ myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/Impl.js Mon May 17 07:14:01 2010
@@ -0,0 +1,518 @@
+/*
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *  under the License.
+ */
+myfaces._impl.core._Runtime.singletonExtendClass("myfaces._impl.core.Impl", Object, {
+
+    //third option myfaces._impl.xhrCoreAjax which will be the new core impl for now
+    _transport : new (myfaces._impl.core._Runtime.getGlobalConfig("transport", myfaces._impl.xhrCore._Ajax))(),
+
+    /**
+     * external event listener queue!
+     */
+    _eventListenerQueue : new (myfaces._impl.core._Runtime.getGlobalConfig("eventListenerQueue", myfaces._impl._util._ListenerQueue))(),
+
+    /**
+     * external error listener queue!
+     */
+    _errorListenerQueue : new (myfaces._impl.core._Runtime.getGlobalConfig("errorListenerQueue", myfaces._impl._util._ListenerQueue))(),
+
+    /*CONSTANTS*/
+
+    /*internal identifiers for options*/
+    _OPT_IDENT_ALL : "@all",
+    _OPT_IDENT_NONE : "@none",
+    _OPT_IDENT_THIS : "@this",
+    _OPT_IDENT_FORM : "@form",
+
+    /*
+     * [STATIC] constants
+     */
+
+    _PROP_PARTIAL_SOURCE : "javax.faces.source",
+    _PROP_VIEWSTATE : "javax.faces.ViewState",
+    _PROP_AJAX : "javax.faces.partial.ajax",
+    _PROP_EXECUTE : "javax.faces.partial.execute",
+    _PROP_RENDER : "javax.faces.partial.render",
+    _PROP_EVENT : "javax.faces.partial.event",
+
+    /* message types */
+    _MSG_TYPE_ERROR : "error",
+    _MSG_TYPE_EVENT : "event",
+
+    /* event emitting stages */
+    _AJAX_STAGE_BEGIN : "begin",
+    _AJAX_STAGE_COMPLETE : "complete",
+    _AJAX_STAGE_SUCCESS : "success",
+
+    /*ajax errors spec 14.4.2*/
+    _ERROR_HTTPERROR : "httpError",
+    _ERROR_EMPTY_RESPONSE : "emptyResponse",
+    _ERROR_MALFORMEDXML : "malformedXML",
+    _ERROR_SERVER_ERROR : "serverError",
+    _ERROR_CLIENT_ERROR : "clientError",
+
+
+
+    /**
+     * collect and encode data for a given form element (must be of type form)
+     * find the javax.faces.ViewState element and encode its value as well!
+     * return a concatenated string of the encoded values!
+     *
+     * @throws error in case of the given element not being of type form!
+     * https://issues.apache.org/jira/browse/MYFACES-2110
+     */
+    getViewState : function(formElement) {
+        /**
+         *  typecheck assert!, we opt for strong typing here
+         *  because it makes it easier to detect bugs
+         */
+        if ('undefined' != typeof formElement && null != formElement) {
+            formElement = myfaces._impl._util._Lang.byId(formElement);
+        }
+
+        if ('undefined' == typeof(formElement)
+                || null == formElement
+                || 'undefined' == typeof(formElement.nodeName)
+                || null == formElement.nodeName
+                || formElement.nodeName.toLowerCase() != "form") {
+            throw new Error("jsf.viewState: param value not of type form!");
+        }
+
+        var ajaxUtils = new myfaces._impl.xhrCore._AjaxUtils(0);
+        return ajaxUtils.encodeSubmittableFields(null, null, null, formElement, null);
+
+    },
+
+    /**
+     * internal assertion check for the element parameter
+     * it cannot be null or undefined
+     * it must be either a string or a valid existing dom node
+     */
+    _assertElement : function(/*String|Dom Node*/ element) {
+        /*namespace remap for our local function context we mix the entire function namespace into
+         *a local function variable so that we do not have to write the entire namespace
+         *all the time
+         **/
+        var _Lang = myfaces._impl._util._Lang;
+
+        /**
+         * assert element
+         */
+        if ('undefined' == typeof( element ) || null == element) {
+            throw new Error("jsf.ajax, element must be set!");
+        }
+        //        if (!JSF2Utils.isString(element) && !(element instanceof Node)) {
+        //            throw new Error("jsf.ajax, element either must be a string or a dom node");
+        //        }
+
+        element = _Lang.byId(element);
+        if ('undefined' == typeof element || null == element) {
+            throw new Error("Element either must be a string to a or must be a valid dom node");
+        }
+    },
+
+    _assertFunction : function(func) {
+        if ('undefined' == typeof func || null == func) {
+            return;
+        }
+        if (!(func instanceof Function)) {
+            throw new Error("Functioncall " + func + " is not a function! ");
+        }
+    },
+
+    /**
+     * this function has to send the ajax requests
+     *
+     * following request conditions must be met:
+     * <ul>
+     *  <li> the request must be sent asynchronously! </li>
+     *  <li> the request must be a POST!!! request </li>
+     *  <li> the request url must be the form action attribute </li>
+     *  <li> all requests must be queued with a client side request queue to ensure the request ordering!</li>
+     * </ul>
+     *
+     * @param {String|Node} element any dom element no matter being it html or jsf, from which the event is emitted
+     * @param {|Event|} event any javascript event supported by that object
+     * @param {|Object|} options  map of options being pushed into the ajax cycle
+     */
+    request : function(element, event, options) {
+
+        /*namespace remap for our local function context we mix the entire function namespace into
+         *a local function variable so that we do not have to write the entire namespace
+         *all the time
+         **/
+        var _Lang = myfaces._impl._util._Lang;
+        var elementId = null;
+        /**
+         * we cross reference statically hence the mapping here
+         * the entire mapping between the functions is stateless
+         */
+        element = _Lang.byId(element);
+        event = ('undefined' == typeof event && window.event) ? window.event : event;
+
+        if ('undefined' != typeof element && null != element) {
+            //detached element handling, we also store the element name
+            //to get a fallback option in case the identifier is not determinable
+            // anymore, in case of a framework induced detachment the element.name should
+            // be shared if the identifier is not determinable anymore
+            elementId = ('undefined' != typeof element.id) ? element.id : null;
+            if ((elementId == null || elementId == '') && 'undefined' != typeof element.name) {
+                elementId = element.name;
+            }
+        }
+
+        /*assert if the onerror is set and once if it is set it must be of type function*/
+        this._assertFunction(options.onerror);
+        /*assert if the onevent is set and once if it is set it must be of type function*/
+        this._assertFunction(options.onevent);
+
+        /*
+         * We make a copy of our options because
+         * we should not touch the incoming params!
+         */
+        var passThroughArguments = _Lang.mixMaps({}, options, true);
+
+        /*additional passthrough cleanup*/
+        /*ie6 supportive code to prevent browser leaks*/
+        passThroughArguments.onevent = null;
+        delete passThroughArguments.onevent;
+        /*ie6 supportive code to prevent browser leaks*/
+        passThroughArguments.onerror = null;
+        delete passThroughArguments.onerror;
+
+        if ('undefined' != typeof event && null != event) {
+            passThroughArguments[this._PROP_EVENT] = event.type;
+        }
+
+        /**
+         * ajax pass through context with the source
+         * onevent and onerror
+         */
+        var ajaxContext = {};
+        ajaxContext.source = element;
+        ajaxContext.onevent = options.onevent;
+        ajaxContext.onerror = options.onerror;
+
+        /**
+         * fetch the parent form
+         */
+
+        var sourceForm = myfaces._impl._util._Dom.fuzzyFormDetection(element);
+        var _Lang = myfaces._impl._util._Lang;
+        if (null == sourceForm && 'undefined' != typeof event && null != event) {
+            sourceForm = myfaces._impl._util._Dom.fuzzyFormDetection(_Lang.getEventTarget(event));
+            if (null == sourceForm) {
+                throw Error("Sourceform could not be determined, either because element is not attached to a form or we have multiple forms with named elements of the same identifier or name, stopping the ajax processing");
+            }
+        } else if (null == sourceForm) {
+            throw Error("Sourceform could not be determined, either because element is not attached to a form or we have multiple forms with named elements of the same identifier or name, stopping the ajax processing");
+        }
+
+        /**
+         * binding contract the javax.faces.source must be set
+         */
+        passThroughArguments[this._PROP_PARTIAL_SOURCE] = elementId;
+
+        /**
+         * javax.faces.partial.ajax must be set to true
+         */
+        passThroughArguments[this._PROP_AJAX] = true;
+
+        /**
+         * if execute or render exist
+         * we have to pass them down as a blank delimited string representation
+         * of an array of ids!
+         */
+        if (_Lang.exists(passThroughArguments, "execute")) {
+            /*the options must be a blank delimited list of strings*/
+            var execString = _Lang.arrayToString(passThroughArguments.execute, ' ');
+            var execNone = execString.indexOf(this._OPT_IDENT_NONE) != -1;
+            var execAll = execString.indexOf(this._OPT_IDENT_ALL) != -1;
+            if (!execNone && !execAll) {
+                execString = execString.replace(this._OPT_IDENT_FORM, sourceForm.id);
+                execString = execString.replace(this._OPT_IDENT_THIS, elementId);
+
+                passThroughArguments[this._PROP_EXECUTE] = execString;
+            } else if (execAll) {
+                passThroughArguments[this._PROP_EXECUTE] = this._OPT_IDENT_ALL;
+            }
+
+            passThroughArguments.execute = null;
+            /*remap just in case we have a valid pointer to an existing object*/
+            delete passThroughArguments.execute;
+        } else {
+            passThroughArguments[this._PROP_EXECUTE] = elementId;
+        }
+
+        if (_Lang.exists(passThroughArguments, "render")) {
+            var renderString = _Lang.arrayToString(passThroughArguments.render, ' ');
+            var renderNone = renderString.indexOf(this._OPT_IDENT_NONE) != -1;
+            var renderAll = renderString.indexOf(this._OPT_IDENT_ALL) != -1;
+            if (!renderNone && !renderAll) {
+                renderString = renderString.replace(this._OPT_IDENT_FORM, sourceForm.id);
+                renderString = renderString.replace(this._OPT_IDENT_THIS, elementId);
+                passThroughArguments[this._PROP_RENDER] = renderString;
+                passThroughArguments.render = null;
+            } else if (renderAll) {
+                passThroughArguments[this._PROP_RENDER] = this._OPT_IDENT_ALL;
+
+            }
+            delete passThroughArguments.render;
+        }
+
+        //implementation specific options are added to the context for further processing
+        if ('undefined' != typeof passThroughArguments.myfaces && null != passThroughArguments.myfaces) {
+            ajaxContext.myfaces = passThroughArguments.myfaces;
+            delete passThroughArguments.myfaces;
+        }
+
+        this._transport.xhrQueuedPost(element, sourceForm, ajaxContext, passThroughArguments);
+
+    },
+
+    addOnError : function(/*function*/errorListener) {
+        /*error handling already done in the assert of the queue*/
+        this._errorListenerQueue.enqueue(errorListener);
+    },
+
+    addOnEvent : function(/*function*/eventListener) {
+        /*error handling already done in the assert of the queue*/
+        this._eventListenerQueue.enqueue(eventListener);
+    },
+
+    /**
+     * implementation triggering the error chain
+     *
+     * @param {Object} request the request object which comes from the xhr cycle
+     * @param {Object} context (Map) the context object being pushed over the xhr cycle keeping additional metadata
+     * @param {String} name the error name
+     * @param {String} serverErrorName the server error name in case of a server error
+     * @param {String} serverErrorMessage the server error message in case of a server error
+     *
+     *  handles the errors, in case of an onError exists within the context the onError is called as local error handler
+     *  the registered error handlers in the queue receiv an error message to be dealt with
+     *  and if the projectStage is at development an alert box is displayed
+     *
+     *  note: we have additional functionality here, via the global config myfaces.config.defaultErrorOutput a function can be provided
+     *  which changes the default output behavior from alert to something else
+     *
+     *
+     */
+    sendError : function sendError(/*Object*/request, /*Object*/ context, /*String*/ name, /*String*/ serverErrorName, /*String*/ serverErrorMessage) {
+        var eventData = {};
+        //we keep this in a closure because we might reuse it for our serverErrorMessage
+        var malFormedMessage = function() {
+            return ('undefined' != typeof name && name == myfaces._impl.core.Impl._ERROR_MALFORMEDXML) ? "The server response could not be parsed, the server has returned with a response which is not xml !" : "";
+        };
+
+        eventData.type = this._MSG_TYPE_ERROR;
+
+        eventData.status = name;
+        eventData.serverErrorName = serverErrorName;
+        eventData.serverErrorMessage = serverErrorMessage;
+
+        try {
+            eventData.source = context.source;
+            eventData.responseCode = request.status;
+            eventData.responseText = request.responseText;
+            eventData.responseXML = request.responseXML;
+        } catch (e) {
+            // silently ignore: user can find out by examining the event data
+        }
+
+        /**/
+        if (myfaces._impl._util._Lang.exists(context, "onerror")) {
+            context.onerror(eventData);
+        }
+
+        /*now we serve the queue as well*/
+        this._errorListenerQueue.broadcastEvent(eventData);
+
+        if (jsf.getProjectStage() === "Development" && this._errorListenerQueue.length() == 0) {
+            var defaultErrorOutput = myfaces._impl.core._Runtime.getGlobalConfig("defaultErrorOutput", alert);
+            var finalMessage = [];
+
+            finalMessage.push(('undefined' != typeof name && null != name) ? name : "");
+            finalMessage.push(('undefined' != typeof serverErrorName && null != serverErrorName) ? serverErrorName : "");
+            finalMessage.push(('undefined' != typeof serverErrorMessage && null != serverErrorMessage) ? serverErrorMessage : "");
+            finalMessage.push(malFormedMessage());
+
+            defaultErrorOutput(finalMessage.join("-") + " Note, this message is only sent, because project stage is development and no " +
+                    "other error listeners are registered.");
+        }
+    },
+
+    /**
+     * sends an event
+     */
+    sendEvent : function sendEvent(/*Object*/request, /*Object*/ context, /*event name*/ name) {
+        var eventData = {};
+        eventData.type = this._MSG_TYPE_EVENT;
+
+        eventData.status = name;
+        eventData.source = context.source;
+
+        if (name !== this._AJAX_STAGE_BEGIN) {
+
+            try {
+                eventData.responseCode = request.status;
+                eventData.responseText = request.responseText;
+                eventData.responseXML = request.responseXML;
+
+            } catch (e) {
+                var impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core.Impl);
+                impl.sendError(request, context, this._ERROR_CLIENT_ERROR, "ErrorRetrievingResponse",
+                        "Parts of the response couldn't be retrieved when constructing the event data: " + e);
+                //client errors are not swallowed
+                throw e;
+            }
+
+        }
+
+        /**/
+        if (myfaces._impl._util._Lang.exists(context, "onevent")) {
+            /*calling null to preserve the original scope*/
+            context.onevent.call(null, eventData);
+        }
+
+        /*now we serve the queue as well*/
+        this._eventListenerQueue.broadcastEvent(eventData);
+    },
+
+    /**
+     * processes the ajax response if the ajax request completes successfully
+     * @param {Object} request (xhrRequest) the ajax request!
+     * @param {Object} context (Map) context map keeping context data not being passed down over
+     * the request boundary but kept on the client
+     */
+    response : function(request, context) {
+        this._transport.response(request, context);
+    },
+
+    /**
+     * @return the project stage also emitted by the server:
+     * it cannot be cached and must be delivered over the server
+     * The value for it comes from the request parameter of the jsf.js script called "stage".
+     */
+    getProjectStage : function() {
+        /* run through all script tags and try to find the one that includes jsf.js */
+        var scriptTags = document.getElementsByTagName("script");
+        for (var i = 0; i < scriptTags.length; i++)
+        {
+            if (scriptTags[i].src.search(/\/javax\.faces\.resource\/jsf\.js.*ln=javax\.faces/) != -1)
+            {
+                /* try to extract stage=XXX */
+                var result = scriptTags[i].src.match(/stage=([^&;]*)/);
+                if (result)
+                {
+                    /* we found stage=XXX */
+                    /* return only valid values of ProjectStage */
+                    if (result[1] == "Production"
+                            || result[1] == "Development"
+                            || result[1] == "SystemTest"
+                            || result[1] == "UnitTest")
+                    {
+                        return result[1];
+                    }
+                }
+                else
+                {
+                    /* we found the script, but there was no stage parameter --> Production */
+                    return "Production";
+                }
+            }
+        }
+        /* we could not find anything valid --> return the default value */
+        return "Production";
+    },
+
+    /**
+     * implementation of the external chain function
+     * moved into the impl
+     *
+     *  @param {Object} source the source which also becomes
+     * the scope for the calling function (unspecified side behavior)
+     * the spec states here that the source can be any arbitrary code block.
+     * Which means it either is a javascript function directly passed or a code block
+     * which has to be evaluated separately.
+     *
+     * After revisiting the code additional testing against components showed that
+     * the this parameter is only targeted at the component triggering the eval
+     * (event) if a string code block is passed. This is behavior we have to resemble
+     * in our function here as well, I guess.
+     *
+     * @param {Event} event the event object being passed down into the the chain as event origin
+     *   the spec is contradicting here, it on one hand defines event, and on the other
+     *   it says it is optional, after asking, it meant that event must be passed down
+     *   but can be undefined
+     */
+    chain : function(source, event) {
+        var len = arguments.length;
+        //the spec is contradicting here, it on one hand defines event, and on the other
+        //it says it is optional, I have cleared this up now
+        //the spec meant the param must be passed down, but can be 'undefined'
+        if (len < 2) {
+            throw new Error(" an event object or unknown must be passed as second parameter ");
+        } else if (len < 3) {
+            if ('function' == typeof event || myfaces._impl._util._Lang.isString(event)) {
+                throw new Error(" an event must be passed down (either a an event object null or undefined) ");
+            }
+            //nothing to be done here, move along
+            return true;
+        }
+        //now we fetch from what is given from the parameter list
+        //we cannot work with splice here in any performant way so we do it the hard way
+        //arguments only are give if not set to undefined even null values!
+
+        //assertions source either null or set as dom element:
+
+        if ('undefined' == typeof source) {
+            throw new Error(" source must be defined");
+            //allowed chain datatypes
+        } else if ('function' == typeof source) {
+            throw new Error(" source cannot be a function (probably source and event were not defined or set to null");
+        }
+        if (myfaces._impl._util._Lang.isString(source)) {
+            throw new Error(" source cannot be a string ");
+        }
+
+        //assertion if event is a function or a string we already are in our function elements
+        //since event either is undefined, null or a valid event object
+
+        if ('function' == typeof event || myfaces._impl._util._Lang.isString(event)) {
+            throw new Error(" an event must be passed down (either a an event object null or undefined) ");
+        }
+
+        for (var loop = 2; loop < len; loop++) {
+            //we do not change the scope of the incoming functions
+            //but we reuse the argument array capabilities of apply
+            var retVal;
+
+            if ('function' == typeof arguments[loop]) {
+                retVal = arguments[loop].call(source, event);
+            } else {
+                //either a function or a string can be passed in case of a string we have to wrap it into another function
+                retVal = new Function("event", arguments[loop]).call(source, event);
+            }
+            //now if one function returns false in between we stop the execution of the cycle
+            //here, note we do a strong comparison here to avoid constructs like 'false' or null triggering
+            if ('undefined' != typeof retVal && retVal === false) {
+                return false;
+            }
+
+        }
+        return true;
+
+    }
+});    

Modified: myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/_Runtime.js
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/_Runtime.js?rev=944995&r1=944994&r2=944995&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/_Runtime.js (original)
+++ myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/_Runtime.js Mon May 17 07:14:01 2010
@@ -315,7 +315,7 @@ if ('undefined' == typeof  myfaces._impl
      * our lazily binding configuration system
      */
     myfaces._impl.core._Runtime.getImpl = function() {
-        myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core._jsfImpl);
+        myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core.Impl);
     };
 
     /**
@@ -489,29 +489,10 @@ if ('undefined' == typeof  myfaces._impl
         }
 
         //we now map the function map in
-        if ('undefined' != typeof prototypeFunctions && null != prototypeFunctions) {
+        if ('undefined' != typeof prototypeFunctions  && null != prototypeFunctions) {
             for (var key in prototypeFunctions) {
-                newClass.prototype[key] = prototypeFunctions[key];
-                //we also can apply a direct _inherited method if the method overwrites an existing one
-                //http://ejohn.org/blog/simple-javascript-inheritance/ i don not eliminate it multiple calls to super
-                //can happen, this is the way dojo does it
-
-                if (null != extendsClass && 'function' == typeof newClass.prototype.parent[key]) {
-                    //we now aop a decorator function on top of everything,
-                    //to make sure we have super set while it is executing
-                    var assignedFunction = newClass.prototype[key];
-
-                    newClass.prototype[key] = function() {
-                        var oldSuper = newClass.prototype["_inherited"];
-                        newClass.prototype["_inherited"] = function() {
-                            this.parent[key].apply(this, arguments);
-                        };
-                        try {
-                            return assignedFunction.apply(this, arguments);
-                        } finally {
-                            newClass.prototype["_inherited"] = oldSuper;
-                        }
-                    }
+                if( key != "_callSuper") {
+                    newClass.prototype[key] = prototypeFunctions[key];
                 }
             }
         }

Modified: myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxRequest.js
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxRequest.js?rev=944995&r1=944994&r2=944995&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxRequest.js (original)
+++ myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxRequest.js Mon May 17 07:14:01 2010
@@ -17,61 +17,102 @@
  * Version: $Revision: 1.4 $ $Date: 2009/05/31 09:16:44 $
  *
  */
-
 /**
- * Constructor
- * @param {Node} source - Item that triggered the request
- * @param {Node} sourceForm (form) - Form containing source
- * @param {Object} context (Map) - AJAX context
- * @param {Object} passThrough (Map) - parameters to pass through to the server (execute/render)
+ * an implementation of a queued
+ * asynchronoues request 
  */
 myfaces._impl.core._Runtime.extendClass("myfaces._impl.xhrCore._AjaxRequest", Object, {
+    _contentType: "application/x-www-form-urlencoded",
+    _source: null,
+    _xhr: null,
+    _partialIdsArray: null,
+    _queueSize: -1,
+    _context:null,
+    response: null,
+    _ajaxUtil: null,
+    _sourceForm: null,
+    _passThrough: null,
+    _requestParameters: null,
+    _exception: null,
+    _timeout: null,
+    _delay:null,
+    _partialIdsArray : null,
+    _alarmThreshold : "ERROR",
+    _xhrQueue: null,
+
+
+    _PAR_ERRORLEVEL:"errorlevel",
+    _PAR_QUEUESIZE:"queuesize",
+    _PAR_PPS:"pps",
+    _PAR_TIMEOUT:"timeout",
+    _PAR_DELAY:"delay",
+
+    _HEAD_POST: "POST",
+    _HEAD_TYPE:"Content-Type",
+    _HEAD_FACES_REQ:"Faces-Request",
+
+    _VAL_AJAX: "partial/ajax",
 
-    constructor_: function(source, sourceForm, context, passThrough) {
-        this.m_exception = new myfaces._impl.xhrCore._Exception("myfaces._impl.xhrCore._AjaxRequest", this.alarmThreshold);
+    /**
+     * Constructor
+     * @param {Node} source - Item that triggered the request
+     * @param {Node} sourceForm (form) - Form containing source
+     * @param {Object} context (Map) - AJAX context
+     * @param {Object} passThrough (Map) - parameters to pass through to the server (execute/render)
+     */
+    constructor_: function(source, sourceForm, context, passThrough, queue) {
+        this._exception = new myfaces._impl.xhrCore._Exception("myfaces._impl.xhrCore._AjaxRequest", this._alarmThreshold);
         try {
-            this.m_contentType = "application/x-www-form-urlencoded";
-            this.m_source = source;
-            this.m_xhr = null;
-            // myfaces parameters
-            this.m_partialIdsArray = null;
-            var errorlevel = 'NONE';
-            this.m_queuesize = -1;
 
             /*namespace remapping for readability*/
             var _Runtime = myfaces._impl.core._Runtime;
             var _Lang = myfaces._impl._util._Lang;
+            var _getConfig = _Runtime.getLocalOrGlobalConfig;
 
-            if (_Runtime.getLocalOrGlobalConfig(context, "errorlevel", null) != null) {
-                errorlevel = context.myfaces.errorlevel;
-            }
-            if (_Runtime.getLocalOrGlobalConfig(context, "queuesize", null) != null) {
-                this.m_queuesize = context.myfaces.queuesize;
-            }
-            if (_Runtime.getLocalOrGlobalConfig(context, "pps", null) != null
-                    && _Lang.exists(passThrough, myfaces._impl.core._jsfImpl._PROP_EXECUTE)
-                    && passThrough[myfaces._impl.core._jsfImpl._PROP_EXECUTE].length > 0) {
-                this.m_partialIdsArray = passThrough[myfaces._impl.core._jsfImpl._PROP_EXECUTE].split(" ");
-            }
-            if (_Runtime.getLocalOrGlobalConfig(context, "timeout", null) != null) {
-                this.m_timeout = context.myfaces.timeout;
-            }
-            if (_Runtime.getLocalOrGlobalConfig(context, "delay", null) != null) {
-                this.m_delay = context.myfaces.delay;
-            }
-            this.m_context = context;
-            this.m_response = new myfaces._impl.xhrCore._AjaxResponse(errorlevel);
-            this.m_ajaxUtil = new myfaces._impl.xhrCore._AjaxUtils(errorlevel);
-            this.m_sourceForm = sourceForm;
-            this.m_passThrough = passThrough;
-            this.m_requestParameters = this.getViewState();
-            for (var key in this.m_passThrough) {
-                this.m_requestParameters = this.m_requestParameters +
+            _Lang.applyArguments(this, arguments, ["source", "sourceForm", "context", "passThrough", "xhrQueue"]);
+
+            //this._source = source;
+            // myfaces parameters
+            //this._partialIdsArray = null;
+            //this._queueSize = -1;
+
+            this._applyConfig("_alarmThreshold", this._PAR_ERRORLEVEL);
+            this._applyConfig("_queueSize", this._PAR_QUEUESIZE);
+            this._applyConfig("_timeout", this._PAR_TIMEOUT);
+            this._applyConfig("_delay", this._PAR_DELAY);
+
+            if (_getConfig(context, this._PAR_PPS, null) != null
+                    && _Lang.exists(passThrough, myfaces._impl.core.Impl._PROP_EXECUTE)
+                    && passThrough[myfaces._impl.core.Impl._PROP_EXECUTE].length > 0) {
+                this._partialIdsArray = passThrough[myfaces._impl.core.Impl._PROP_EXECUTE].split(" ");
+            }
+
+            //this._queue = queue;
+            //this._context = context;
+            this.response = new myfaces._impl.xhrCore._AjaxResponse(this._alarmThreshold);
+            this._ajaxUtil = new myfaces._impl.xhrCore._AjaxUtils(this._alarmThreshold);
+            //this._sourceForm = sourceForm;
+            //this._passThrough = passThrough;
+
+            this._requestParameters = this.getViewState();
+
+            for (var key in this._passThrough) {
+                this._requestParameters = this._requestParameters +
                         "&" + encodeURIComponent(key) +
-                        "=" + encodeURIComponent(this.m_passThrough[key]);
+                        "=" + encodeURIComponent(this._passThrough[key]);
             }
+
         } catch (e) {
-            this.m_exception.throwError(null, context, "Ctor", e);
+            //_onError
+            this._exception.throwError(null, context, "Ctor", e);
+        }
+    },
+
+    _applyConfig: function(destParm, srcParm) {
+        var _Runtime = myfaces._impl.core._Runtime;
+        var _getConfig = _Runtime.getLocalOrGlobalConfig;
+        if (_getConfig(this._context, srcParm, null) != null) {
+            this[destParm] = _getConfig(this._context, srcParm, null);
         }
     },
 
@@ -80,33 +121,33 @@ myfaces._impl.core._Runtime.extendClass(
      */
     send : function() {
         try {
-            var ajaxRequestQueue = myfaces._impl.xhrCore._AjaxRequestQueue.queue;
 
-            this.m_xhr = myfaces._impl.core._Runtime.getXHRObject();
+            this._xhr = myfaces._impl.core._Runtime.getXHRObject();
 
-            this.m_xhr.open("POST", this.m_sourceForm.action, true);
-            this.m_xhr.setRequestHeader("Content-Type", this.m_contentType);
-            this.m_xhr.setRequestHeader("Faces-Request", "partial/ajax");
-            this.m_xhr.onreadystatechange = myfaces._impl.xhrCore._AjaxRequestQueue.handleCallback;
-            var _Impl =  myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core._jsfImpl);
-            _Impl.sendEvent(this.m_xhr, this.m_context, myfaces._impl.core._jsfImpl._AJAX_STAGE_BEGIN);
-            this.m_xhr.send(this.m_requestParameters);
-            if ('undefined' != typeof this.m_timeout) {
+            this._xhr.open(this._HEAD_POST, this._sourceForm.action, true);
+            this._xhr.setRequestHeader(this._HEAD_TYPE, this._contentType);
+            this._xhr.setRequestHeader(this._HEAD_FACES_REQ, this._VAL_AJAX);
+
+            this._xhr.onreadystatechange = this._xhrQueue.handleCallback;
+            var _Impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core.Impl);
+            _Impl.sendEvent(this._xhr, this._context, myfaces._impl.core.Impl._AJAX_STAGE_BEGIN);
+            this._xhr.send(this._requestParameters);
+            if ('undefined' != typeof this._timeout) {
                 var timeoutId = window.setTimeout(
                         function() {
                             try {
-                                if (ajaxRequestQueue.m_request.m_xhr.readyState > 0
-                                        && ajaxRequestQueue.queue.m_request.m_xhr.readyState < 4) {
-                                    ajaxRequestQueue.queue.m_request.m_xhr.abort();
+                                if (this._xhrQueue._curReq._xhr.readyState > 0
+                                        && this._xhrQueue._curReq._xhr.readyState < 4) {
+                                    this._xhrQueue._curReq._xhr.abort();
                                 }
                             } catch (e) {
                                 // don't care about exceptions here
                             }
-                        }, this.m_timeout);
+                        }, this._timeout);
             }
         } catch (e) {
-            this.m_exception.throwError(this.m_xhr, this.m_context, "send", e);
-
+            //_onError//_onError
+            this._exception.throwError(this._xhr, this._context, "send", e);
         }
     },
 
@@ -118,34 +159,39 @@ myfaces._impl.core._Runtime.extendClass(
         var READY_STATE_DONE = 4;
         try {
             //local namespace remapping
-            var _Impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core._jsfImpl);
+            var _Impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core.Impl);
 
-            if (this.m_xhr.readyState == READY_STATE_DONE) {
-                if (this.m_xhr.status >= 200 && this.m_xhr.status < 300) {
-                    _Impl.sendEvent(this.m_xhr, this.m_context, myfaces._impl.core._jsfImpl._AJAX_STAGE_COMPLETE);
-                    _Impl.response(this.m_xhr, this.m_context);
-                    _Impl.sendEvent(this.m_xhr, this.m_context, myfaces._impl.core._jsfImpl._AJAX_STAGE_SUCCESS);
-                    myfaces._impl.xhrCore._AjaxRequestQueue.queue.processQueue();
+            if (this._xhr.readyState == READY_STATE_DONE) {
+                //_onDone
+                _Impl.sendEvent(this._xhr, this._context, myfaces._impl.core.Impl._AJAX_STAGE_COMPLETE);
+
+                if (this._xhr.status >= 200 && this._xhr.status < 300) {
+                     //_onSuccess
+                    _Impl.response(this._xhr, this._context);
+                    _Impl.sendEvent(this._xhr, this._context, myfaces._impl.core.Impl._AJAX_STAGE_SUCCESS);
+                    this._xhrQueue.processQueue();
                 } else {
-                    _Impl.sendEvent(this.m_xhr, this.m_context, myfaces._impl.core._jsfImpl._AJAX_STAGE_COMPLETE);
+                    //_onError
                     var errorText;
                     try {
                         errorText = "Request failed";
-                        if (this.m_xhr.status) {
-                            errorText += "with status " + this.m_xhr.status;
-                            if (this.m_xhr.statusText) {
-                                errorText += " and reason " + this.m_xhr.statusText;
+                        if (this._xhr.status) {
+                            errorText += "with status " + this._xhr.status;
+                            if (this._xhr.statusText) {
+                                errorText += " and reason " + this._xhr.statusText;
                             }
                         }
                     } catch (e) {
                         errorText = "Request failed with unknown status";
                     }
-                    _Impl.sendError(this.m_xhr, this.m_context, myfaces._impl.core._jsfImpl._ERROR_HTTPERROR,
-                            myfaces._impl.core._jsfImpl._ERROR_HTTPERROR, errorText);
+                    //_onError
+                    _Impl.sendError(this._xhr, this._context, myfaces._impl.core.Impl._ERROR_HTTPERROR,
+                            myfaces._impl.core.Impl._ERROR_HTTPERROR, errorText);
                 }
             }
         } catch (e) {
-            this.m_exception.throwError(this.m_xhr, this.m_context, "requestCallback", e);
+            //_onError
+            this._exception.throwError(this._xhr, this._context, "requestCallback", e);
         }
     },
 
@@ -157,8 +203,8 @@ myfaces._impl.core._Runtime.extendClass(
      *             and javax.faces.ViewState element
      */
     getViewState : function() {
-        return this.m_ajaxUtil.processUserEntries(this.m_xhr, this.m_context, this.m_source,
-                this.m_sourceForm, this.m_partialIdsArray);
+        return this._ajaxUtil.encodeSubmittableFields(this._xhr, this._context, this._source,
+                this._sourceForm, this._partialIdsArray);
     }
 
 });

Modified: myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxRequestQueue.js
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxRequestQueue.js?rev=944995&r1=944994&r2=944995&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxRequestQueue.js (original)
+++ myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxRequestQueue.js Mon May 17 07:14:01 2010
@@ -1,118 +1,125 @@
-/*
- * Copyright 2009 Ganesh Jung
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Author: Ganesh Jung (latest modification by $Author: ganeshpuri $)
- * Version: $Revision: 1.3 $ $Date: 2009/05/31 09:16:44 $
- *
- */
-if (myfaces._impl.core._Runtime.reserveNamespace("myfaces._impl.xhrCore._AjaxRequestQueue")) {
-    //TODO this class needs namespace cleanups
-
-    /**
-     * Constructor
-     */
-    myfaces._impl.xhrCore._AjaxRequestQueue = function() {
-        this.m_request = null;
-        this.m_queuedRequests = [];
-        this.m_exception = new myfaces._impl.xhrCore._Exception("myfaces._impl.xhrCore._AjaxRequestQueue", "NONE");
-    };
-
-    /**
-     * [STATIC PROPERTIES]
-     */
-    myfaces._impl.xhrCore._AjaxRequestQueue.queue = new myfaces._impl.xhrCore._AjaxRequestQueue();
-
-    /**
-     * [STATIC]
-     * provides api callback
-     */
-    myfaces._impl.xhrCore._AjaxRequestQueue.handleCallback = function() {
-        if (myfaces._impl.xhrCore._AjaxRequestQueue.queue.m_request != null) {
-            myfaces._impl.xhrCore._AjaxRequestQueue.queue.m_request.requestCallback();
-        } else {
-            myfaces._impl.xhrCore._AjaxRequestQueue.queue.m_exception.throwWarning
-            (null, null, "doRequestCallback", "No request object available");
-        }
-    };
-
-    /**
-     * delay request, then call queueNow
-     * @param {myfaces._impl.xhrCore._AjaxRequest} request - request to send
-     */
-    myfaces._impl.xhrCore._AjaxRequestQueue.prototype.queueRequest = function(request) {
-        if (typeof request.m_delay == "number") {
-        	this.clearDelayTimeout();
-            this.delayTimeoutId = window.setTimeout(
-            	function() {
-            		myfaces._impl.xhrCore._AjaxRequestQueue.queue.clearDelayTimeout();
-                	myfaces._impl.xhrCore._AjaxRequestQueue.queue.queueNow(request);
-            	}, request.m_delay);
-        } else {
-        	this.queueNow(request);
-        }
-    };
-
-    myfaces._impl.xhrCore._AjaxRequestQueue.prototype.clearDelayTimeout = function() {
-		try {
-			if (typeof this.delayTimeoutId == "number") {
-				window.clearTimeout(this.delayTimeoutId);
-				delete this.delayTimeoutId;
-			}
-		} catch (e) {
-			// already timed out
-		}
-    }
-
-    /**
-     * send a request or keep it in a queue
-     * @param {myfaces._impl.xhrCore._AjaxRequest} request - request to send
-     */
-    myfaces._impl.xhrCore._AjaxRequestQueue.prototype.queueNow = function(request) {
-        if (this.m_request == null) {
-            this.m_request = request;
-            this.m_request.send();
-        } else {
-            this.m_queuedRequests.push(request);
-            if (request.m_queuesize > -1 && request.m_queuesize < this.m_queuedRequests.length)
-                this.m_queuedRequests.shift();
-        }
-    };
-
-    /**
-     * process queue, send request, if exists
-     */
-    myfaces._impl.xhrCore._AjaxRequestQueue.prototype.processQueue = function() {
-        if (this.m_queuedRequests.length > 0) {
-            // Using Javascripts build-in queue capabilities here!
-            // JSF RI is using Delayed Shift Queue (DSQ), which starts to outperform the build-in queue
-            // when queue size exceeds ~10 requests (http://safalra.com/web-design/javascript/queues/).
-            // With JSF Ajax the queue will hardly ever reach this size.
-            this.m_request = this.m_queuedRequests.shift();
-            this.m_request.send();
-        } else {
-            this.m_request = null;
-        }
-    };
-
-    /**
-     * cleanup queue
-     */
-    myfaces._impl.xhrCore._AjaxRequestQueue.prototype.clearQueue = function() {
-        this.m_request = null;
-        this.m_queuedRequest = null;
-        this.m_requestPending = false;
-    };
-
+/*
+ * Copyright 2009 Ganesh Jung
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Ganesh Jung (latest modification by $Author: ganeshpuri $)
+ * Version: $Revision: 1.3 $ $Date: 2009/05/31 09:16:44 $
+ *
+ */
+myfaces._impl.core._Runtime.extendClass("myfaces._impl.xhrCore._AjaxRequestQueue", myfaces._impl._util._Queue, {
+
+    _curReq : null,
+
+    constructor_: function(){
+        this._callSuper("constructor");
+
+        var _this = this;
+
+        var _handleCallback = this.handleCallback;
+        //we have to scope this because the xhr request will change the
+        //callback scope to window from outside, hence we have to enforce a scope here
+        this.handleCallback = myfaces._impl._util._Lang.hitch(_this, _handleCallback);
+    },
+
+    /**
+     *
+     * provides api callback
+     *
+     * we have to hitch this function since
+     * the xhr request changes scopes
+     * in the asynchronous case, the callback always
+     * has to reference this
+     */
+    handleCallback : function() {
+
+        if (this._curReq != null) {
+            this._curReq.requestCallback();
+            //this.processQueue();
+        }
+    },
+
+    /**
+     * delay request, then call queueNow
+     * @param {Object} request (myfaces._impl.xhrCore._AjaxRequest) request to send
+     */
+    queueRequest : function(request) {
+        if (typeof request._delay == "number") {
+            this.clearDelayTimeout();
+            var _Lang = myfaces._impl._util._Lang;
+            this.delayTimeoutId = window.setTimeout(
+                    _Lang.hitch(this, function() {
+                        this.clearDelayTimeout();
+                        this.queueNow(request);
+                    }), request._delay);
+        } else {
+            this.enqueue(request);
+        }
+    },
+
+    /**
+     * timeout clearing routine
+     * for timeout requests
+     */
+    clearDelayTimeout : function() {
+        try {
+            if (typeof this.delayTimeoutId == "number") {
+                window.clearTimeout(this.delayTimeoutId);
+                delete this.delayTimeoutId;
+            }
+        } catch (e) {
+            // already timed out
+        }
+    },
+
+    /**
+     * send a request or keep it in a queue
+     * @param {myfaces._impl.xhrCore._AjaxRequest} request - request to send
+     */
+    enqueue : function(request) {
+        if (this._curReq == null) {
+            this._curReq = request;
+            this._curReq.send();
+        } else {
+
+            this._callSuper("enqueue",request);
+            if (request._queueSize != this._queueSize) {
+                this.setQueueSize(request._queueSize);
+            }
+        }
+    },
+
+    /**
+     * process queue, send request, if exists
+     */
+    processQueue: function() {
+        this._curReq = this.dequeue();
+        if (null != this._curReq) {
+            this._curReq.send();
+        }
+    },
+
+    /**
+     * cleanup queue
+     */
+    cleanup: function() {
+        this._curReq = null;
+        this._callSuper("cleanup");
+    }
+});
+
+//TODO replace this with a singleton hooked to the direct xhr object
+//instead of one hooked to the qeue
+if (myfaces._impl.core._Runtime.reserveNamespace("myfaces._impl.xhrCore._RQInstance")) {
+    myfaces._impl.xhrCore._RQInstance = new myfaces._impl.xhrCore._AjaxRequestQueue();
 }
\ No newline at end of file