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 2009/02/05 17:13:18 UTC

svn commit: r741158 - in /myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces: _util/_JSF2Utils.js _util/_Logger.js ajax/jsf.js

Author: werpu
Date: Thu Feb  5 16:13:17 2009
New Revision: 741158

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

ongoing works in the ajax event handling, since the latest released sources of the ri are different to the spec information, the code has been made compatible to the latest released public ri sources! Also since the trinidad based logging facilities were suboptimal a decend javascript logging framework has been added, the code for backwards compatibility has been preserved so that  it still can be called from JSF2Utils (maybe changed later)

Next step implementation of the error handlers, and rechecking if we are still compatible to the RI in this regard!
(Trinidad might do different things in the event handling of the ajax core!)


Added:
    myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces/_util/_Logger.js
Modified:
    myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces/_util/_JSF2Utils.js
    myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces/ajax/jsf.js

Modified: myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces/_util/_JSF2Utils.js
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces/_util/_JSF2Utils.js?rev=741158&r1=741157&r2=741158&view=diff
==============================================================================
--- myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces/_util/_JSF2Utils.js (original)
+++ myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces/_util/_JSF2Utils.js Thu Feb  5 16:13:17 2009
@@ -15,9 +15,7 @@
  *  under the License.
  */
 
-if('undefined' == typeof org || null == org) {
-    var org = null;
-}
+var myfaces = null;
 /**
  * A simple provide function
  * fixing the namespaces
@@ -28,12 +26,8 @@
      *
      * reserve the root namespace for myfaces
      */
-    if ('undefined' != typeof OpenAjax && ('undefined' == typeof org || null == org || 'undefined' == typeof org.apache || 'undefined' == typeof myfaces ||
-        null == org.apache || null == myfaces)) {
-        if(undefined == typeof(org) || null == org) {
-            OpenAjax.hub.registerLibrary("myfaces", "myfaces.apache.org", "1.0", null);
-        }
-
+    if ('undefined' != typeof OpenAjax && ( 'undefined' == typeof myfaces || null == myfaces)) {
+        OpenAjax.hub.registerLibrary("myfaces", "myfaces.apache.org", "1.0", null);
     }
 
     /*originally we had it at org.apache.myfaces, but we are now down to myfaces since the openajax seems to have problems registering more than a root domain and org is not only apache specific*/
@@ -57,6 +51,8 @@
     myfaces._JSF2Utils = function() {
         }
     myfaces._JSF2Utils._underTest = false;
+    myfaces._JSF2Utils._logger = null;
+
     myfaces._JSF2Utils.isUnderTest = function() {
         return this._underTest;
     }
@@ -193,22 +189,45 @@
             return method.apply(scope, arguments || []);
         }; // Function
     };
+    /*used internally to lazy init the logger*/
+    myfaces._JSF2Utils._getLogger = function() {
+        if(null ==  myfaces._JSF2Utils._logger) {
+            myfaces._JSF2Utils._logger = myfaces._Logger.getInstance();
+        }
+    };
+
     // Logging helper for use in Firebug
     /*static*/
-    myfaces._JSF2Utils.logWarning = function(varArgs)
+    myfaces._JSF2Utils.logWarning = function(varArgs/*,...*/)
     {
-        if (window.console && console.warn)
-            console.warn(arguments);
+        var logger = myfaces._JSF2Utils._getLogger();
+        logger.warn(varArgs);
     // else???
-    }
+    };
+
+    myfaces._JSF2Utils.logDebug = function(varArgs/*,...*/)
+    {
+        var logger = myfaces._JSF2Utils._getLogger();
+        logger.debug(varArgs);
+    // else???
+    };
+
+
+    myfaces._JSF2Utils.logInfo = function(varArgs/*,...*/)
+    {
+        var logger = myfaces._JSF2Utils._getLogger();
+        logger.info(varArgs);
+    // else???
+    };
+
     // Logging helper for use in Firebug
     /*static*/
-    myfaces._JSF2Utils.logError = function(varArgs)
+    myfaces._JSF2Utils.logError = function(varArgs/*,...*/)
     {
-        if (window.console && console.error)
-            console.error(arguments);
-    // else???
-    }
+        var logger = myfaces._JSF2Utils._getLogger();
+        logger.error(varArgs);
+    };
+
     myfaces._JSF2Utils._hitchArgs = function(scope, method /*,...*/) {
         var pre = this._toArray(arguments, 2);
         var named = this.isString(method);
@@ -266,14 +285,24 @@
      * check if an element exists in the root
      */
     myfaces._JSF2Utils.exists = function(root, element) {
-        return ('undefined' != typeof root[element] && null != root[element]);
+        return ('undefined' != typeof root && null != root &&  'undefined' != typeof root[element] && null != root[element]);
     }
 
+
+
     myfaces._JSF2Utils.arrayToString = function(/*String or array*/ arr, /*string*/ delimiter) {
-        if(myfaces._JSF2Utils.isString(arr)) {
-            return arr;
-        }
-        return arr.join(delimiter);
+      if( myfaces._JSF2Utils.isString(arr) ) {
+        return arr;
+      }
+      var resultArr = [];
+      for(var cnt = 0; cnt < arr.length; cnt ++) {
+          if(myfaces._JSF2Utils.isString(arr[cnt])) {
+              resultArr.push(arr[cnt]);
+          } else {
+              resultArr.push(arr[cnt].toString());
+          }
+      }
+      return resultArr.join(delimiter);
     };
 
     /**

Added: myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces/_util/_Logger.js
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces/_util/_Logger.js?rev=741158&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces/_util/_Logger.js (added)
+++ myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces/_util/_Logger.js Thu Feb  5 16:13:17 2009
@@ -0,0 +1,102 @@
+/**
+ * Generical simplified browser independend logger
+ * on browsers which offer a console object
+ * it logs into the
+ *
+ * It follows a factory pattern so that it can be reroutet
+ * to other debugging divs!
+ *
+ * The output is either to the console if present
+ * or to a debugging div
+ * or to the outer document if nothing is present
+ */
+
+_reserveMyfaces();
+
+if(!myfaces._JSF2Utils.exists(myfaces, "_Logger")) {
+    myfaces._Logger = function() {
+        var targetDiv = document.getElementById("log_console");
+        this._targetDiv = targetDiv;/*null or a valid element*/
+        this._logLevel  = this.LOG_LEVEL_ALL;
+        this._hasConsole = ('undefined' != typeof console && null != typeof console);
+        
+    };
+    myfaces._Logger._loggerIdx = {};
+
+    myfaces._Logger.prototype.LOG_LEVEL_ALL      = 1;
+    myfaces._Logger.prototype.LOG_LEVEL_DEBUG    = 2;
+    myfaces._Logger.prototype.LOG_LEVEL_ERROR    = 3;
+    myfaces._Logger.prototype.LOG_LEVEL_WARN     = 4;
+    myfaces._Logger.prototype.LOG_LEVEL_INFO     = 5;
+    myfaces._Logger.prototype.LOG_LEVEL_OFF      = 6;
+
+    myfaces._Logger.getInstance = function(targetDiv) {
+        var retVal = null;
+        var targetDivId = null;
+        if('undefined' != typeof(targetDiv) && null != targetDiv) {
+            targetDivId = myfaces._JSF2Utils.isString(targetDiv) ? targetDiv : targetDiv.id;
+            retVal = myfaces._Logger._loggerIdx[targetDivId];
+            if('undefined' != typeof retVal || null != retVal) {
+                return retVal;
+            }
+        }
+        retVal = new myfaces._Logger();
+
+        if('undefined' != typeof(targetDiv) && null != targetDiv) {
+            retVal.setTargetDiv(targetDiv);
+            myfaces._Logger._loggerIdx[targetDivId] = retVal;
+        }
+        return retVal;
+    };
+
+    myfaces._Logger.prototype._setLogLevel = function(/*int*/ logLevel) {
+        this._logLevel = logLevel;
+    };
+
+    myfaces._Logger.prototype._setTargetDiv = function(/*String*/ targetDiv) {
+        targetDiv = document.getElementById(targetDiv);
+        this._targetDiv = targetDiv;/*null or a valid element*/
+    };
+
+    myfaces._Logger.prototype.debug = function(/*Object*/varArgs/*,...*/) {
+        if(this._logLevel > this.LOG_LEVEL_DEBUG) return;
+
+        if(this._hasConsole) {
+            console.debug(varArgs)
+        } else if(null != this._targetDiv) {
+            this._targetDiv.innerHTML = this._targetDiv.innerHTML + "<br /> [DEBUG] : "+ myfaces._JSF2Utils.arrayToString(arguments, " ");
+        } else { /*in case a target fails we use document.write*/
+            document.write("<br /> [DEBUG] : " + myfaces._JSF2Utils.arrayToString(arguments, " "));
+        }
+    };
+    myfaces._Logger.prototype.error = function(varArgs/*,...*/) {
+        if(this._logLevel > this.LOG_LEVEL_ERROR) return;
+        if(this._hasConsole) {
+            console.error(varArgs)
+        } else if(null != this._targetDiv) {
+            this._targetDiv.innerHTML = this._targetDiv.innerHTML + "<br /> [ERROR] : " + myfaces._JSF2Utils.arrayToString(arguments, " ");
+        } else { /*in case a target fails we use document.write*/
+            document.write("<br /> [ERROR] : "+ myfaces._JSF2Utils.arrayToString(arguments, " "));
+        }
+    };
+    myfaces._Logger.prototype.warn = function(varArgs/*,...*/) {
+        if(this._logLevel > this.LOG_LEVEL_WARN) return;
+        if(this._hasConsole) {
+            console.warn(varArgs)
+        } else if(null != this._targetDiv) {
+            this._targetDiv.innerHTML = this._targetDiv.innerHTML + "<br /> [WARN] : " + myfaces._JSF2Utils.arrayToString(arguments, " ");
+        } else { /*in case a target fails we use document.write*/
+            document.write("<br /> [WARN] : "+ myfaces._JSF2Utils.arrayToString(arguments, " "));
+        }
+    };
+    myfaces._Logger.prototype.info = function(/*Object*/varArgs/*,...*/) {
+        if(this._logLevel > this.LOG_LEVEL_WARN) return;
+        if(this._hasConsole) {
+            console.info(varArgs)
+        } else if(null != this._targetDiv) {
+            this._targetDiv.innerHTML = this._targetDiv.innerHTML + "<br /> [INFO] : "+ myfaces._JSF2Utils.arrayToString(arguments, " ");
+        } else { /*in case a target fails we use document.write*/
+            document.write("<br /> [INFO] : "+ myfaces._JSF2Utils.arrayToString(arguments, " "));
+        }
+    };
+}
\ No newline at end of file

Modified: myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces/ajax/jsf.js
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces/ajax/jsf.js?rev=741158&r1=741157&r2=741158&view=diff
==============================================================================
--- myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces/ajax/jsf.js (original)
+++ myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces/ajax/jsf.js Thu Feb  5 16:13:17 2009
@@ -19,6 +19,14 @@
  *  Those are the central public functions in the JSF2
  *  Ajax API! They handle the entire form submit and ajax send
  *  and resolve cycle!
+ *
+ *
+ *  TODO isolate the entire Trinidad part in a neutral
+ *  framework adapter class so that we can switch
+ *  transport implementations on the fly without
+ *  touching the core code (so that we might be able
+ *  to check for an existing transport and hook into that one
+ *  to keep the javascript size down)
  */
 
 /**
@@ -38,7 +46,34 @@
     jsf.ajax = new Object();
 }
 
+/*CONSTANTS*/
+
+jsf.ajax._PROP_PARTIAL_SOURCE = "javax.faces.partial.source";
+jsf.ajax._PROP_VIEWSTATE = "javax.faces.viewState";
+jsf.ajax._PROP_AJAX = "javax.faces.partial.ajax";
+jsf.ajax._PROP_EXECUTE = "javax.faces.partial.execute";
+jsf.ajax._PROP_RENDER = "javax.faces.partial.render";
+
+
+jsf.ajax._MSG_TYPE_ERROR = "error";
+jsf.ajax._MSG_TYPE_EVENT = "event";
+jsf.ajax._AJAX_STAGE_BEGIN = "begin";
+jsf.ajax._AJAX_STAGE_COMPLETE = "complete";
+jsf.ajax._AJAX_STAGE_HTTPERROR = "httpError";
+
+/*Event queues*/
 jsf.ajax._requestQueue = new myfaces._TrRequestQueue();
+
+/**
+ * external event listener queue!
+ */
+jsf.ajax._eventListenerQueue = new myfaces._ListenerQueue();
+
+/**
+ * external error listener queue!
+ */
+jsf.ajax._errorListenerQueue = new myfaces._ListenerQueue();
+
 /**
  * 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!
@@ -62,7 +97,7 @@
     }
     var formValues = {};
 
-    formValues["javax.faces.viewState"] = document.getElementById("javax.faces.viewState").value;
+    formValues[jsf.ajax._PROP_VIEWSTATE] = document.getElementById(jsf.ajax._PROP_VIEWSTATE).value;
     formValues = myfaces._JSF2Utils.getPostbackContent(formElement, formValues);
     return formValues;
 };
@@ -174,10 +209,6 @@
      * we should not touch the incoming params!
      */
     var passThroughArguments = JSF2Utils.mixMaps({}, options, true);
-
-    //finalOptions["javax.faces.viewState"]       = JSFAjax.viewState(parentForm);
-    //finalOptions = JSF2Utils.mixMaps(finalOptions, options, true);
-
     var viewState = jsf.getViewState(sourceForm);
 
     /*
@@ -192,7 +223,7 @@
      * binding contract the javax.faces.partial.source must be
      * set according to the december 2008 preview
      */
-    passThroughArguments["javax.faces.partial.source"] = sourceElement.id;
+    passThroughArguments[jsf.ajax._PROP_PARTIAL_SOURCE] = sourceElement.id;
 
     /*
      * we pass down the name and value of the source element
@@ -205,7 +236,7 @@
     /*
      * javax.faces.partial.ajax must be set to true
      */
-    passThroughArguments["javax.faces.partial.ajax"] = true;
+    passThroughArguments[jsf.ajax._PROP_AJAX] = true;
 
     /**
      * if execute or render exist
@@ -215,15 +246,15 @@
     if(JSF2Utils.exists(passThroughArguments,"execute")) {
         /*the options must be a blank delimited list of strings*/
         //TODO add the source id to the list
-        passThroughArguments["javax.faces.partial.execute"] = JSF2Utils.arrayToString(passThroughArguments.execute,' ');
+        passThroughArguments[jsf.ajax._PROP_EXECUTE] = JSF2Utils.arrayToString(passThroughArguments.execute,' ');
         passThroughArguments.execute = null;/*remap just in case we have a valid pointer to an existing object*/
         delete passThroughArguments.execute;
     } else {
-         passThroughArguments["javax.faces.partial.execute"] = sourceElement.id;
+        passThroughArguments[jsf.ajax._PROP_EXECUTE] = sourceElement.id;
     }
     if(JSF2Utils.exists(passThroughArguments,"render")) {
         //TODO add the source id to the list
-        passThroughArguments["javax.faces.partial.render"] = JSF2Utils.arrayToString(passThroughArguments.render, ' ');
+        passThroughArguments[jsf.ajax._PROP_RENDER] = JSF2Utils.arrayToString(passThroughArguments.render, ' ');
         passThroughArguments.execute = null;
         delete passThroughArguments.execute;
     }
@@ -271,20 +302,109 @@
      */
 };
 
+jsf.ajax.addOnError = function(/*function*/errorListener) {
+    /*error handling already done in the assert of the queue*/
+    jsf.ajax._errorListenerQueue.add(errorListener);
+}
+
+jsf.ajax.addOnEvent = function(/*function*/eventListener) {
+    /*error handling already done in the assert of the queue*/
+    jsf.ajax._eventListenerQueue.add(eventListener);
+}
+
+
+/**
+ * RI compatibility method
+ * TODO make sure this method also occurrs in the specs
+ * otherwise simply pull it
+ */
+jsf.ajax.sendError = function sendError(/*Object*/request,/*Object*/ context,/*String*/ name,/*String*/ serverErrorName,/*String*/ serverErrorMessage) {
+    var eventData = {};
+    eventData.type = jsf.ajax._MSG_TYPE_ERROR;
+
+    eventData.name = name;
+    eventData.source = context.source;
+    eventData.responseXML = request.responseXML;
+    eventData.responseText = request.responseText;
+    eventData.responseCode = request.status;
+
+    /**/
+    if(myfaces._JSF2Utils.exists(context, "onerror")) {
+        context.onerror(eventData);
+    }
+    /*now we serve the queue as well*/
+    jsf.ajax._errorListenerQueue.broadcastEvent(eventData);
+};
+
+/**
+ * RI compatibility method
+ * TODO make sure this method also occurrs in the specs
+ * otherwise simply pull it
+ */
+jsf.ajax.sendEvent = function sendEvent(/*Object*/request,/*Object*/ context,/*even name*/ name) {
+    var eventData = {};
+    eventData.type = jsf.ajax._MSG_TYPE_EVENT;
+
+    eventData.name = name;
+    eventData.source = context.source;
+    if (name !== jsf.ajax._AJAX_STAGE_BEGIN) {
+        eventData.responseXML =  request.responseXML;
+        eventData.responseText = request.responseText;
+        eventData.responseCode = request.status;
+    }
+
+    /**/
+    if(myfaces._JSF2Utils.exists(context, "onevent")) {
+        /*calling null to preserve the original scope*/
+        context.onevent.call(null, eventData);
+    }
+    /*now we serve the queue as well*/
+    jsf.ajax._eventListenerQueue.broadcastEvent(eventData);
+}
+
+
+
 /**
  * Maps an internal Trinidad xmlhttprequest event
  * into one compatible with the events of the ri
  * this is done for compatibility purposes
  * since trinidad follows similar rules regarding
  * the events we just have to map the eventing accordingly
+ *
+ * note I am implementing this after reading the ri code
+ *
  */
 jsf.ajax._mapTrinidadToRIEvents = function(/*object*/ xhrContext,/*_TrXMLRequestEvent*/ event) {
+    var complete = false;
 
-    //TODO do the mapping code here
-    var riEvent = {};
-
-    //TODO add the event mapping code here
-    return null;
+    switch(event.getStatus()) {
+        //TODO add mapping code here
+        case myfaces._TrXMLRequestEvent.STATUS_QUEUED:
+            break; /*we have to wait*/
+        case myfaces._TrXMLRequestEvent.STATUS_SEND_BEFORE:
+            jsf.ajax.sendEvent(null, xhrContext, jsf.ajax._AJAX_STAGE_BEGIN)
+            break;;
+        case myfaces._TrXMLRequestEvent.STATUS_SEND_AFTER:
+            /*still waiting, we can add listeners later if it is allowed*/
+            break;
+        case myfaces._TrXMLRequestEvent.STATUS_COMPLETE:
+            /**
+            *here we can do our needed callbacks so
+            *that the specification is satisfied
+            **/
+            complete = true;
+            var responseStatusCode = event.getResponseStatusCode();
+            if(200 <= responseStatusCode && 300 > responseStatusCode ) {
+                jsf.ajax.sendEvent(event.getRequest(), xhrContext, jsf.ajax._AJAX_STAGE_COMPLETE);
+            } else {
+                jsf.ajax.sendEvent(event.getRequest(), xhrContext, jsf.ajax._AJAX_STAGE_COMPLETE);
+                jsf.ajax.sendError(event.getRequest(), xhrContext, jsf.ajax._AJAX_STAGE_HTTPERROR);
+            }
+            break;
+        default:
+            break;
+    }
+    return complete;
 };
 
 /**
@@ -307,16 +427,15 @@
 
     /**
      *generally every callback into this method must issue an event
-
-
-    /*
-     * we now can handle the onerror and onevent decently
-     * maybe we also have to remap the response function as well
-     * lets see!
-     * (Check the specs and RI for that)
      */
+    var complete = jsf.ajax._mapTrinidadToRIEvents(context, event);
 
-    jsf.ajax.ajaxResponse(event.getRequest());
+    /**
+     * the standard incoming events are handled appropriately we now can deal with the response
+     */
+    if(complete) {
+        jsf.ajax.ajaxResponse(event.getRequest());
+    }
 }
 /**
  * processes the ajax response if the ajax request completes successfully