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/04/03 12:23:01 UTC
svn commit: r761599 - in
/myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces:
_util/_xhr/_SimpleXHRFrameworkAdapter.js _util/_xhr/_SimpleXHRTransport.js
ajax/jsf.js ajax/jsf_impl.js
Author: werpu
Date: Fri Apr 3 10:23:01 2009
New Revision: 761599
URL: http://svn.apache.org/viewvc?rev=761599&view=rev
Log:
https://issues.apache.org/jira/browse/MYFACES-2176
Added:
myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces/ajax/jsf_impl.js
Modified:
myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces/_util/_xhr/_SimpleXHRFrameworkAdapter.js
myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces/_util/_xhr/_SimpleXHRTransport.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/_xhr/_SimpleXHRFrameworkAdapter.js
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces/_util/_xhr/_SimpleXHRFrameworkAdapter.js?rev=761599&r1=761598&r2=761599&view=diff
==============================================================================
--- myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces/_util/_xhr/_SimpleXHRFrameworkAdapter.js (original)
+++ myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces/_util/_xhr/_SimpleXHRFrameworkAdapter.js Fri Apr 3 10:23:01 2009
@@ -50,9 +50,10 @@
var complete = false;
/*here we have to do the event mapping back into the ri events*/
- //TODO check whether the scope changes on the sendEvent so that we have to bind it to our context!
+ //onEvent and onError are served on the JSF side as well!
+
+
switch(request.readyState) {
- //TODO add mapping code here
case xhrConst.READY_STATE_OPENED:
jsf.ajax.sendEvent(null, xhrContext, jsf.ajax._AJAX_STAGE_BEGIN)
break;
@@ -62,12 +63,12 @@
*that the specification is satisfied
**/
complete = true;
- var responseStatusCode = event.status;
+
+ var responseStatusCode = request.status;
if(200 <= responseStatusCode && 300 > responseStatusCode ) {
jsf.ajax.sendEvent(request, xhrContext, jsf.ajax._AJAX_STAGE_COMPLETE);
- //TODO do the dom manipulation callback here
jsf.ajax.response(request, xhrContext);
} else {
jsf.ajax.sendEvent(request, xhrContext, jsf.ajax._AJAX_STAGE_COMPLETE);
@@ -84,12 +85,13 @@
* central request callback
*/
myfaces._SimpleXHRFrameworkAdapter.prototype.sendRequest = function(ajaxContext, action, viewState, passThroughArguments ) {
- var data = {};
- data.context = ajaxContext;
- data.action = action;
- data.viewstate = viewState;
- data.passthroughArguments = passThroughArguments;
- this._delegate.send(data);
+ var requestData = {};
+ requestData.context = ajaxContext;
+ requestData.action = action;
+ requestData.viewstate = viewState;
+ requestData.passthroughArguments = passThroughArguments;
+
+ this._delegate.send(requestData);
};
}
Modified: myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces/_util/_xhr/_SimpleXHRTransport.js
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces/_util/_xhr/_SimpleXHRTransport.js?rev=761599&r1=761598&r2=761599&view=diff
==============================================================================
--- myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces/_util/_xhr/_SimpleXHRTransport.js (original)
+++ myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces/_util/_xhr/_SimpleXHRTransport.js Fri Apr 3 10:23:01 2009
@@ -32,7 +32,6 @@
*/
_reserveMyfaces();
-
if (!myfaces._JSF2Utils.exists(myfaces, "_SimpleXHRTransport")) {
myfaces._SimpleXHRTransport = function() {
/*we need an instance of our utils for the hitch function*/
@@ -48,7 +47,7 @@
this._cached = false;
this._eventListeners = new myfaces._ListenerQueue();
-
+
/*
* caching data queue forw cached
* ajax post requests!
@@ -56,7 +55,6 @@
this._transportDataQueue = [];
};
-
myfaces._SimpleXHRTransport.prototype.addEventListener = function(/*function*/ eventListener) {
this._eventListeners.add(eventListener);
};
@@ -66,17 +64,17 @@
myfaces._SimpleXHRTransport.prototype._handleXHREvent = function() {
/*handle the event callbach*/
-
+
var data = this._transportDataQueue[0];
this._eventListeners.broadcastEvent(data);
-
- if(data.transport.readyState === this.xhrConst.READY_STATE_DONE) {
+
+ if (data.transport.readyState === this.xhrConst.READY_STATE_DONE) {
this._transportDataQueue.shift();
this._process(true);
/*ie cleanup*/
delete data.transport;
}
-
+
return true;
};
@@ -86,57 +84,57 @@
* or after terminating an xhr request from the inside
* we have to cover this that way because of a callback error in mozilla
*/
- myfaces._SimpleXHRTransport.prototype._process = function( /*boolean*/ inProcess) {
+ myfaces._SimpleXHRTransport.prototype._process = function(/*boolean*/ inProcess) {
try {
-
+
var size = this._transportDataQueue.length;
- if(size > 1 && !inProcess) return; /*still in queue no send can be issued*/
- if(size === 0) {
-
- return; /*empty queue process has to terminate*/
- }
+ if (size > 1 && !inProcess) return;
+ /*still in queue no send can be issued*/
+ if (size === 0) {
+ return;
+ /*empty queue process has to terminate*/
+ }
/*note this only works this way because javascript multitasks only premptively
*if a real multithreading is added please put the outer send into a critical region
*to prevent concurrency issues*/
- var data = this._transportDataQueue[0];
+ var queueData = this._transportDataQueue[0];
- data.transport = this._utils.getXHR();
+ queueData.transport = this._utils.getXHR();
- var transport = data.transport;
- var passThrough = data.passthroughArguments;
+ var transport = queueData.transport;
+ var passThrough = queueData.passthroughArguments;
- if(!this._utils.isString(passThrough)) {
+ if (!this._utils.isString(passThrough)) {
passThrough = this._utils.getPostbackContentFromMap(passThrough);
}
- if(!this._cached) { //we bypass any caching if needed!
+ if (!this._cached) { //we bypass any caching if needed!
//set the pragmas here as well
- data.action = data.action + ((data.action.indexOf('?') == -1) ? "?" :"&" )+ "AjaxRequestUniqueId = "+(new Date().getTime());
+ queueData.action = queueData.action + ((queueData.action.indexOf('?') == -1) ? "?" : "&" ) + "AjaxRequestUniqueId = " + (new Date().getTime());
}
/**
* We set the on ready state change here
*/
-
+
transport.onreadystatechange = this._utils.hitch(this, this._handleXHREvent);
- transport.open(this._sendMethod, data.action, this._async);
- if(this._utils.exists(transport, "setRequestHeader")) {
+ transport.open(this._sendMethod, queueData.action, this._async);
+ if (this._utils.exists(transport, "setRequestHeader")) {
transport.setRequestHeader(this.xhrConst.FACES_REQUEST, this.xhrConst.PARTIAL_AJAX);
transport.setRequestHeader(this.xhrConst.CONTENT_TYPE, this.xhrConst.XFORM_ENCODED);
}
-
+
//THE RI does a notification here
//be we rely on the official W3C codes
//which should be sufficient for the callback
//on "begin"
- transport.send(data.viewstate +"&"+ passThrough);
-
+ transport.send(queueData.viewstate + "&" + passThrough);
} catch (e) {
//Browser error...
/*internal error we log it and then we splice the affected event away*/
- myfaces._Logger.getInstance().error("Error in myfaces._SimpleXHRTransport.prototype._process", e);
- if(this._transportDataQueue.length > 0) {
+ myfaces._Logger.getInstance().error("Error in myfaces._SimpleXHRTransport.prototype._process", e);
+ if (this._transportDataQueue.length > 0) {
this._transportDataQueue.shift();
}
}
@@ -156,6 +154,7 @@
myfaces._SimpleXHRTransport.prototype.send = function(/*Object*/data) {
var queueData = {};
+
queueData.context = data.context;
queueData.action = data.action;
queueData.viewstate = data.viewstate;
@@ -163,7 +162,7 @@
this._transportDataQueue.push(queueData);
/*we initiate a send if none is in progress currently*/
-
+
this._process(false);
};
}
\ 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=761599&r1=761598&r2=761599&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 Fri Apr 3 10:23:01 2009
@@ -16,21 +16,12 @@
/**
*MyFaces core javascripting libraries
*
- * Those are the central public functions in the JSF2
+ * Those are the central public API 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)
*/
/**
- *
* reserve the root namespace
*/
if ('undefined' != typeof OpenAjax && ('undefined' == typeof jsf || null == typeof jsf)) {
@@ -44,416 +35,84 @@
if ('undefined' == typeof jsf.ajax || null == jsf.ajax) {
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._PROP_ALL = "@all";
-jsf.ajax._PROP_NONE = "@none";
-
-/*partial response types*/
-jsf.ajax._RESPONSE_PARTIAL = "partial-response";
-jsf.ajax._RESPONSETYPE_ERROR = "error";
-jsf.ajax._RESPONSETYPE_REDIRECT = "redirect";
-jsf.ajax._RESPONSETYPE_REDIRECT = "changes";
-
-/*partial commands*/
-jsf.ajax._PCMD_UPDATE = "update";
-jsf.ajax._PCMD_DELETE = "delete";
-jsf.ajax._PCMD_INSERT = "insert";
-jsf.ajax._PCMD_EVAL = "eval";
-jsf.ajax._PCMD_ATTRIBUTES = "attributes";
-jsf.ajax._PCMD_EXTENSION = "extension";
-
-/*various errors within the rendering stage*/
-jsf.ajax._ERROR_EMPTY_RESPONSE = "emptyResponse";
-jsf.ajax._ERROR_MALFORMEDXML = "malformedXML";
-jsf.ajax._MSG_SUCCESS = "success";
-
-/*various ajax message types*/
-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";
-
-/*Transports including queues and adapters!*/
-jsf.ajax._xhrAdapter = ('undefined' != typeof (myfaces._SimpleXHRFrameworkAdapter)) ? new myfaces._SimpleXHRFrameworkAdapter() : new myfaces._TrinidadFrameworkAdapter();
-
-/**
- * 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!
- * return a concatenated string of the encoded values!
- *
- * @throws an exception in case of the given element not being of type form!
- * https://issues.apache.org/jira/browse/MYFACES-2110
- */
-jsf.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
- || 'undefined' == typeof(formElement.nodeName)
- || null == formElement.nodeName
- || formElement.nodeName != "FORM") {
- throw Exception("jsf.viewState: param value not of type form!");
- }
- var formValues = {};
-
- formValues[jsf.ajax._PROP_VIEWSTATE] = document.getElementById(jsf.ajax._PROP_VIEWSTATE).value;
- formValues = myfaces._JSF2Utils.getPostbackContent(formElement, formValues);
- return formValues;
-};
-
-/**
- * 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
- */
-jsf.ajax._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 JSF2Utils = myfaces._JSF2Utils;
-
- /**
- * assert element
- */
- if ('undefined' == typeof( element ) || null == element) {
- throw new Exception("jsf.ajax, element must be set!");
- }
- if (!JSF2Utils.isString(element) && !(element instanceof Node)) {
- throw new Exception("jsf.ajax, element either must be a string or a dom node");
- }
-
- element = JSF2Utils.byId(element);
- if ('undefined' == typeof element || null == element) {
- throw new Exception("Element either must be a string to a or must be a valid dom node");
- }
-
-};
-
-jsf.ajax._assertFunction = function(/*Objec*/ obj, /*String*/ functionName) {
- if ('undefined' == typeof(obj) || null == obj) return;
- var func = obj[functionName];
- if ('undefined' == typeof func || null == func) {
- return;
- }
- if (!(func instanceof Function)) {
- throw new Exception("Functioncall " + func + " is not a function! ");
- }
-}
-/**
- * Captures the event arguments according to the list in the specification
- */
-jsf.ajax._caputureEventArgs = function(/*Dom node*/node, /*event*/ obj) {
+ //todo make this overridable by a configuration option
/*
- * TODO encode the rest of the arguments
- * once it is clear what has to be done here
+ myfaces.
*/
- var retVal = {};
- return retVal;
-};
-
-/**
- * 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 element: any dom element no matter being it html or jsf, from which the event is emitted
- * @param event: any javascript event supported by that object
- * @param options : map of options being pushed into the ajax cycle
- */
-jsf.ajax.request = function(/*String|Dom Node*/ element, /*|EVENT|*/ event, /*{|OPTIONS|}*/ 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 JSF2Utils = myfaces._JSF2Utils;
+ jsf.ajax._impl = new myfaces._jsfImpl();
/**
- * we cross reference statically hence the mapping here
- * the entire mapping between the functions is stateless
+ * 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 an exception in case of the given element not being of type form!
+ * https://issues.apache.org/jira/browse/MYFACES-2110
*/
- var JSFAjax = jsf.ajax;
-
- /*assert a valid structure of a given element*/
- JSFAjax._assertElement(element);
- /*assert if the onerror is set and once if it is set it must be of type function*/
- JSFAjax._assertFunction(options, "onerror");
- /*assert if the onevent is set and once if it is set it must be of type function*/
- JSFAjax._assertFunction(options, "onevent");
+ jsf.ajax.getViewState = function(formElement) {
+ return jsf.ajax._impl.getViewState(formElement);
+ };
/**
- * fetch the parent form first
+ * 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 element: any dom element no matter being it html or jsf, from which the event is emitted
+ * @param event: any javascript event supported by that object
+ * @param options : map of options being pushed into the ajax cycle
*/
- var sourceForm = JSF2Utils.getParentForm(element);
+ jsf.ajax.request = function(/*String|Dom Node*/ element, /*|EVENT|*/ event, /*{|OPTIONS|}*/ options) {
+ return jsf.ajax._impl.request(element, event, options);
+ };
- if ('undefined' == typeof sourceForm || null == sourceForm) {
- sourceForm = document.forms[0];
+ jsf.ajax.addOnError = function(/*function*/errorListener) {
+ return jsf.ajax._impl.addOnError(errorListener);
}
- /*
- * We make a copy of our options because
- * we should not touch the incoming params!
- */
- var passThroughArguments = JSF2Utils.mixMaps({}, options, true);
- var viewState = jsf.getViewState(sourceForm);
-
- /*
- * either we have a valid form element or an element then we have to pass the form
- * if it is a dummy element we have to pass it down as additional parameter
- * the same applies to non form elements which cannot hold values
- * but have ids!
- */
- var sourceElement = JSF2Utils.byId(element);
-
- /*
- * binding contract the javax.faces.partial.source must be
- * set according to the december 2008 preview
- */
- passThroughArguments[jsf.ajax._PROP_PARTIAL_SOURCE] = sourceElement.id;
-
- /*
- * we pass down the name and value of the source element
- * seems to be removed on the ri side
- * the have it in our viewstate values anyway
- * and also in the exectute if no other values are set!
- */
- //passThroughArguments[sourceElement.name || sourceElement.id] = sourceElement.value || 'x';
-
- /*
- * javax.faces.partial.ajax must be set to true
- */
- passThroughArguments[jsf.ajax._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 (JSF2Utils.exists(passThroughArguments, "execute")) {
- /*the options must be a blank delimited list of strings*/
- //TODO add the source id to the list
- 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[jsf.ajax._PROP_EXECUTE] = sourceElement.id;
+ jsf.ajax.addOnEvent = function(/*function*/eventListener) {
+ return jsf.ajax._impl.addOnError(errorListener);
}
- if (JSF2Utils.exists(passThroughArguments, "render")) {
- //TODO add the source id to the list
- passThroughArguments[jsf.ajax._PROP_RENDER] = JSF2Utils.arrayToString(passThroughArguments.render, ' ');
- passThroughArguments.execute = null;
- delete passThroughArguments.execute;
- }
-
- /*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.onevent;
-
- var extractedEventArguments = JSFAjax._caputureEventArgs(element, event);
-
- /*we mixin the event params but do not override existing ones!*/
- passThroughArguments = JSF2Utils.mixMaps(passThroughArguments, extractedEventArguments, false);
-
- /*according to the specs we only deal with queued asynchronous events in our transport layer!*/
-
- //TODO encode all parameters including the viewstate
-
- //TODO we have to deal with the onerror
- //and onevent handlers with our own Trinidad derived ajax engine
/**
- * ajax pass through context with the source
- * onevent and onerror
+ * RI compatibility method
+ * TODO make sure this method also occurrs in the specs
+ * otherwise simply pull it
*/
- var ajaxContext = {};
- ajaxContext.source = element;
- ajaxContext.onevent = options.onevent;
- ajaxContext.onerror = options.onerror;
+ jsf.ajax.sendError = function sendError(/*Object*/request, /*Object*/ context, /*String*/ name, /*String*/ serverErrorName, /*String*/ serverErrorMessage) {
+ jsf.ajax._impl.sendError(request, context, name, serverErrorName, serverErrorMessage);
+ };
/**
- * we now use the trinidad request queue to send down the ajax request
+ * RI compatibility method
+ * TODO make sure this method also occurrs in the specs
+ * otherwise simply pull it
*/
- JSFAjax._xhrAdapter.sendRequest(ajaxContext, sourceForm.action, viewState, passThroughArguments);
-
- /*
- * TODO #61
- * https://issues.apache.org/jira/browse/MYFACES-2112
- * done
- */
-};
-
-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);
-}
-
-/**
- * processes the ajax response if the ajax request completes successfully
- * @param request the ajax request!
- */
-jsf.ajax.response = function(/*xhr request object*/request, context) {
- if ('undefined' == typeof(request) || null == request) {
- throw Exception("jsf.ajaxResponse: The response cannot be null or empty!");
+ jsf.ajax.sendEvent = function sendEvent(/*Object*/request, /*Object*/ context, /*even name*/ name) {
+ jsf.ajax._impl.sendEvent(request, context, name);
}
- if (!myfaces._JSF2Utils.exists(request, "responseXML")) {
- jsf.ajax.sendError(request, context, jsf.ajax._ERROR_EMPTY_RESPONSE);
-
- return;
- }
-
- var xmlContent = request.responseXML;
- if (xmlContent.firstChild.tagName == "parsererror") {
- jsf.ajax.sendError(request, context, jsf.ajax._ERROR_MALFORMEDXML);
- return;
- }
-
- var partials = xmlContent.getElementsByTagName(jsf.ajax._RESPONSE_PARTIAL);
- if ('undefined' == typeof partials || partials == null || partials.length != 1) {
- jsf.ajax.sendError(request, context, jsf.ajax._ERROR_MALFORMEDXML);
- return;
- }
-
- var partialXmlData = partials[0];
- var childNodesLength = partialXmlData.childNodes.length;
-
- for (var loop = 0; loop < childNodesLength; loop++) {
- var childNode = partialXmlData.childNodes[loop];
- var nodeName = childNode.nodeName.toLowerCase();
-
- if (nodeName == jsf.ajax._PCMD_EVAL) {
- // jsf.ajax._handleEval(childNode);
- } else if (nodeName == jsf.ajax._PCMD_UPDATE) {
- // jsf.ajax._handleUpdate(childNode);
- } else if (nodeName == jsf.ajax._PCMD_INSERT) {
- // jsf.ajax._handleInsert(childNode);
- } else if (nodeName == jsf.ajax._PCMD_DELETE) {
- // jsf.ajax._handleDelete(childNode);
- } else if (nodeName == jsf.ajax._PCMD_ATTRIBUTES) {
- // jsf.ajax._handleAtttributes(childNode);
- } else if (nodeName == jsf.ajax._PCMD_EXTENSION) {
- // jsf.ajax._handleExtension(childNode);
- } else {
- jsf.ajax.sendError(request, context, jsf.ajax._ERROR_MALFORMEDXML);
- return;
- }
- }
- jsf.ajax.sendEvent(request, context, jsf.ajax._MSG_SUCCESS);
-
/**
- * TODO #62
- * https://issues.apache.org/jira/browse/MYFACES-2114
+ * processes the ajax response if the ajax request completes successfully
+ * @param request the ajax request!
*/
-};
-/**
- * @return the current project state emitted by the server side method:
- * javax.faces.application.Application.getProjectStage()
- */
-jsf.getProjectStage = function() {
-
- if ('undefined' == typeof(this._projectStage) ||
- null == this._projectStage) {
- //TODO add small templating capabilities to our resource loader
- //so that the project stage is loaded on the fly!
- //or solve it with a separate xmlhttprequest
- }
-
+ jsf.ajax.response = function(/*xhr request object*/request, context) {
+ jsf.ajax._impl.response(request, context);
+ };
/**
- * TODO #62
- * https://issues.apache.org/jira/browse/MYFACES-2115
+ * @return the current project state emitted by the server side method:
+ * javax.faces.application.Application.getProjectStage()
*/
- return this._projectStage;
-};
-
+ jsf.ajax.getProjectStage = function() {
+ return jsf.ajax._impl.getProjectStage();
+ };
+}
Added: myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces/ajax/jsf_impl.js
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces/ajax/jsf_impl.js?rev=761599&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces/ajax/jsf_impl.js (added)
+++ myfaces/core/branches/2_0_0/api/src/main/javascript/META-INF/resources/javax/faces/ajax/jsf_impl.js Fri Apr 3 10:23:01 2009
@@ -0,0 +1,458 @@
+/*
+ * 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.
+ */
+
+_reserveMyfaces();
+
+if (!myfaces._JSF2Utils.exists(myfaces, "_jsfImpl")) {
+
+ myfaces._jsfImpl = function() {
+
+ /*Transports including queues and adapters!*/
+ this._requestHandler = ('undefined' != typeof (myfaces._SimpleXHRFrameworkAdapter)) ? new myfaces._SimpleXHRFrameworkAdapter() : new myfaces._TrinidadFrameworkAdapter();
+
+ /*Response handler to isolate the ppr specific parts*/
+ //myfaces._jsfImpl.prototype._responseHandler = new myfaces._ResponseHandler();
+
+ /**
+ * external event listener queue!
+ */
+ this._eventListenerQueue = new myfaces._ListenerQueue();
+
+ /**
+ * external error listener queue!
+ */
+ this._errorListenerQueue = new myfaces._ListenerQueue();
+
+ };
+
+ /*CONSTANTS*/
+
+ myfaces._jsfImpl.prototype._PROP_PARTIAL_SOURCE = "javax.faces.partial.source";
+ myfaces._jsfImpl.prototype._PROP_VIEWSTATE = "javax.faces.viewState";
+ myfaces._jsfImpl.prototype._PROP_AJAX = "javax.faces.partial.ajax";
+ myfaces._jsfImpl.prototype._PROP_EXECUTE = "javax.faces.partial.execute";
+ myfaces._jsfImpl.prototype._PROP_RENDER = "javax.faces.partial.render";
+ myfaces._jsfImpl.prototype._PROP_EVENT = "javax.faces.partial.event";
+
+ /*internal identifiers for options*/
+ myfaces._jsfImpl.prototype._OPT_IDENT_ALL = "@all";
+ myfaces._jsfImpl.prototype._OPT_IDENT_NONE = "@none";
+ myfaces._jsfImpl.prototype._OPT_IDENT_THIS = "@this";
+ myfaces._jsfImpl.prototype._OPT_IDENT_FORM = "@form";
+
+ /*partial response types*/
+ myfaces._jsfImpl.prototype._RESPONSE_PARTIAL = "partial-response";
+ myfaces._jsfImpl.prototype._RESPONSETYPE_ERROR = "error";
+ myfaces._jsfImpl.prototype._RESPONSETYPE_REDIRECT = "redirect";
+ myfaces._jsfImpl.prototype._RESPONSETYPE_REDIRECT = "changes";
+
+ /*partial commands*/
+ myfaces._jsfImpl.prototype._PCMD_UPDATE = "update";
+ myfaces._jsfImpl.prototype._PCMD_DELETE = "delete";
+ myfaces._jsfImpl.prototype._PCMD_INSERT = "insert";
+ myfaces._jsfImpl.prototype._PCMD_EVAL = "eval";
+ myfaces._jsfImpl.prototype._PCMD_ATTRIBUTES = "attributes";
+ myfaces._jsfImpl.prototype._PCMD_EXTENSION = "extension";
+
+ /*various errors within the rendering stage*/
+ myfaces._jsfImpl.prototype._ERROR_EMPTY_RESPONSE = "emptyResponse";
+ myfaces._jsfImpl.prototype._ERROR_MALFORMEDXML = "malformedXML";
+ myfaces._jsfImpl.prototype._MSG_SUCCESS = "success";
+
+ /*various ajax message types*/
+ myfaces._jsfImpl.prototype._MSG_TYPE_ERROR = "error";
+ myfaces._jsfImpl.prototype._MSG_TYPE_EVENT = "event";
+ myfaces._jsfImpl.prototype._AJAX_STAGE_BEGIN = "begin";
+ myfaces._jsfImpl.prototype._AJAX_STAGE_COMPLETE = "complete";
+ myfaces._jsfImpl.prototype._AJAX_STAGE_HTTPERROR = "httpError";
+
+ /**
+ * 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 an exception in case of the given element not being of type form!
+ * https://issues.apache.org/jira/browse/MYFACES-2110
+ */
+ myfaces._jsfImpl.prototype.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
+ || 'undefined' == typeof(formElement.nodeName)
+ || null == formElement.nodeName
+ || formElement.nodeName != "FORM") {
+ throw Exception("jsf.viewState: param value not of type form!");
+ }
+ var formValues = {};
+
+ formValues[this._PROP_VIEWSTATE] = document.getElementById(this._PROP_VIEWSTATE).value;
+ formValues = myfaces._JSF2Utils.getPostbackContent(formElement, formValues);
+ return formValues;
+ };
+
+ /**
+ * 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
+ */
+ myfaces._jsfImpl.prototype._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 JSF2Utils = myfaces._JSF2Utils;
+
+ /**
+ * assert element
+ */
+ if ('undefined' == typeof( element ) || null == element) {
+ throw new Exception("jsf.ajax, element must be set!");
+ }
+ if (!JSF2Utils.isString(element) && !(element instanceof Node)) {
+ throw new Exception("jsf.ajax, element either must be a string or a dom node");
+ }
+
+ element = JSF2Utils.byId(element);
+ if ('undefined' == typeof element || null == element) {
+ throw new Exception("Element either must be a string to a or must be a valid dom node");
+ }
+
+ };
+
+ myfaces._jsfImpl.prototype._assertFunction = function(/*Objec*/ obj, /*String*/ functionName) {
+ if ('undefined' == typeof(obj) || null == obj) return;
+ var func = obj[functionName];
+ if ('undefined' == typeof func || null == func) {
+ return;
+ }
+ if (!(func instanceof Function)) {
+ throw new Exception("Functioncall " + func + " is not a function! ");
+ }
+ }
+
+ /**
+ * Captures the event arguments according to the list in the specification
+ */
+ myfaces._jsfImpl.prototype._caputureEventArgs = function(/*Dom node*/node, /*event*/ obj) {
+ /*
+ * TODO encode the rest of the arguments
+ * once it is clear what has to be done here
+ */
+ var retVal = {};
+ return retVal;
+ };
+
+ /**
+ * 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 element: any dom element no matter being it html or jsf, from which the event is emitted
+ * @param event: any javascript event supported by that object
+ * @param options : map of options being pushed into the ajax cycle
+ */
+ myfaces._jsfImpl.prototype.request = function(/*String|Dom Node*/ element, /*|EVENT|*/ event, /*{|OPTIONS|}*/ 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 JSF2Utils = myfaces._JSF2Utils;
+
+ /**
+ * we cross reference statically hence the mapping here
+ * the entire mapping between the functions is stateless
+ */
+
+ /*assert a valid structure of a given element*/
+ this._assertElement(element);
+ /*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");
+
+ /**
+ * fetch the parent form first
+ */
+ var sourceForm = JSF2Utils.getParentForm(element);
+
+ if ('undefined' == typeof sourceForm || null == sourceForm) {
+ sourceForm = document.forms[0];
+ }
+
+ /*
+ * We make a copy of our options because
+ * we should not touch the incoming params!
+ */
+ var passThroughArguments = JSF2Utils.mixMaps({}, options, true);
+ var viewState = jsf.ajax.getViewState(sourceForm);
+
+ /*
+ * either we have a valid form element or an element then we have to pass the form
+ * if it is a dummy element we have to pass it down as additional parameter
+ * the same applies to non form elements which cannot hold values
+ * but have ids!
+ */
+ var sourceElement = JSF2Utils.byId(element);
+
+ /*
+ * binding contract the javax.faces.partial.source must be
+ * set according to the december 2008 preview
+ */
+ passThroughArguments[this._PROP_PARTIAL_SOURCE] = sourceElement.id;
+
+ /*
+ * we pass down the name and value of the source element
+ * seems to be removed on the ri side
+ * the have it in our viewstate values anyway
+ * and also in the exectute if no other values are set!
+ */
+ //passThroughArguments[sourceElement.name || sourceElement.id] = sourceElement.value || 'x';
+
+ /*
+ * 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 (JSF2Utils.exists(passThroughArguments, "execute")) {
+ /*the options must be a blank delimited list of strings*/
+ var execString = JSF2Utils.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, sourceElement.id);
+
+ 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] = sourceElement.id;
+ }
+ if (JSF2Utils.exists(passThroughArguments, "render")) {
+ var renderString = JSF2Utils.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, sourceElement.id);
+ passThroughArguments[this._PROP_RENDER] = JSF2Utils.arrayToString(passThroughArguments.render, ' ');
+ passThroughArguments.render = null;
+ } else if (renderAll) {
+ passThroughArguments[this._PROP_RENDER] = this._OPT_IDENT_ALL;
+
+ }
+ delete passThroughArguments.render;
+ } else {
+ passThroughArguments[this._PROP_RENDER] = sourceElement.id;
+ }
+
+ /*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.onevent;
+
+ var extractedEventArguments = this._caputureEventArgs(element, event);
+
+ if ('undefined' != typeof event && null != event) {
+ passThroughArguments[this._PROP_EVENT] = event.type;
+ }
+
+ /*we mixin the event params but do not override existing ones!*/
+
+ passThroughArguments = JSF2Utils.mixMaps(passThroughArguments, extractedEventArguments, false);
+
+ /**
+ * ajax pass through context with the source
+ * onevent and onerror
+ */
+ var ajaxContext = {};
+ ajaxContext.source = element;
+ ajaxContext.onevent = options.onevent;
+ ajaxContext.onerror = options.onerror;
+
+ /**
+ * we now use the trinidad request queue to send down the ajax request
+ */
+ this._requestHandler.sendRequest(ajaxContext, sourceForm.action, viewState, passThroughArguments);
+
+ /*
+ * TODO #61
+ * https://issues.apache.org/jira/browse/MYFACES-2112
+ * done
+ */
+ };
+
+ myfaces._jsfImpl.prototype.addOnError = function(/*function*/errorListener) {
+ /*error handling already done in the assert of the queue*/
+ this._errorListenerQueue.add(errorListener);
+ }
+
+ myfaces._jsfImpl.prototype.addOnEvent = function(/*function*/eventListener) {
+ /*error handling already done in the assert of the queue*/
+ this._eventListenerQueue.add(eventListener);
+ }
+
+ /**
+ * RI compatibility method
+ * TODO make sure this method also occurrs in the specs
+ * otherwise simply pull it
+ */
+ myfaces._jsfImpl.prototype.sendError = function sendError(/*Object*/request, /*Object*/ context, /*String*/ name, /*String*/ serverErrorName, /*String*/ serverErrorMessage) {
+ var eventData = {};
+ eventData.type = this._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*/
+ this._errorListenerQueue.broadcastEvent(eventData);
+ };
+
+ /**
+ * RI compatibility method
+ * TODO make sure this method also occurrs in the specs
+ * otherwise simply pull it
+ */
+ myfaces._jsfImpl.prototype.sendEvent = function sendEvent(/*Object*/request, /*Object*/ context, /*even name*/ name) {
+ var eventData = {};
+ eventData.type = this._MSG_TYPE_EVENT;
+
+ eventData.name = name;
+ eventData.source = context.source;
+ if (name !== this._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*/
+ this._eventListenerQueue.broadcastEvent(eventData);
+ }
+
+ /**
+ * processes the ajax response if the ajax request completes successfully
+ * @param request the ajax request!
+ */
+ myfaces._jsfImpl.prototype.response = function(/*xhr request object*/request, context) {
+ if ('undefined' == typeof(request) || null == request) {
+ throw Exception("jsf.ajaxResponse: The response cannot be null or empty!");
+ }
+
+ if (!myfaces._JSF2Utils.exists(request, "responseXML")) {
+ this.sendError(request, context, this._ERROR_EMPTY_RESPONSE);
+
+ return;
+ }
+
+ var xmlContent = request.responseXML;
+ if (xmlContent.firstChild.tagName == "parsererror") {
+ this.sendError(request, context, this._ERROR_MALFORMEDXML);
+ return;
+ }
+
+ var partials = xmlContent.getElementsByTagName(this._RESPONSE_PARTIAL);
+ if ('undefined' == typeof partials || partials == null || partials.length != 1) {
+ this.sendError(request, context, this._ERROR_MALFORMEDXML);
+ return;
+ }
+
+ var partialXmlData = partials[0];
+ var childNodesLength = partialXmlData.childNodes.length;
+
+ for (var loop = 0; loop < childNodesLength; loop++) {
+ var childNode = partialXmlData.childNodes[loop];
+ var nodeName = childNode.nodeName.toLowerCase();
+
+ if (nodeName == this._PCMD_EVAL) {
+ // this._responseHandler.doEval(childNode);
+ } else if (nodeName == this._PCMD_UPDATE) {
+ // this._responseHandler.doUpdate(childNode);
+ } else if (nodeName == this._PCMD_INSERT) {
+ // this._responseHandler.doInsert(childNode);
+ } else if (nodeName == this._PCMD_DELETE) {
+ // this._responseHandler.doDelete(childNode);
+ } else if (nodeName == this._PCMD_ATTRIBUTES) {
+ // this._responseHandler.doAtttributes(childNode);
+ } else if (nodeName == this._PCMD_EXTENSION) {
+ // this._responseHandler.doExtension(childNode);
+ } else {
+ this.sendError(request, context, this._ERROR_MALFORMEDXML);
+ return;
+ }
+ }
+ this.sendEvent(request, context, this._MSG_SUCCESS);
+
+ /**
+ * TODO #62
+ * https://issues.apache.org/jira/browse/MYFACES-2114
+ */
+ };
+ /**
+ * @return the current project state emitted by the server side method:
+ * javax.faces.application.Application.getProjectStage()
+ */
+ myfaces._jsfImpl.prototype.getProjectStage = function() {
+
+ if ('undefined' == typeof(this._projectStage) ||
+ null == this._projectStage) {
+ //TODO add small templating capabilities to our resource loader
+ //so that the project stage is loaded on the fly!
+ //or solve it with a separate xmlhttprequest
+ }
+
+ /**
+ * TODO #62
+ * https://issues.apache.org/jira/browse/MYFACES-2115
+ */
+ return this._projectStage;
+ };
+
+}