1 /*
  2  * Licensed to the Apache Software Foundation (ASF) under one or more
  3  * contributor license agreements.  See the NOTICE file distributed with
  4  * this work for additional information regarding copyright ownership.
  5  * The ASF licenses this file to you under the Apache License, Version 2.0
  6  * (the "License"); you may not use this file except in compliance with
  7  * the License.  You may obtain a copy of the License at
  8  *
  9  *      http://www.apache.org/licenses/LICENSE-2.0
 10  *
 11  * Unless required by applicable law or agreed to in writing, software
 12  * distributed under the License is distributed on an "AS IS" BASIS,
 13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  * See the License for the specific language governing permissions and
 15  * limitations under the License.
 16 */
 17 
 18 /**
 19  *MyFaces core javascripting libraries
 20  *
 21  *  Those are the central public API functions in the JSF2
 22  *  Ajax API! They handle the entire form submit and ajax send
 23  *  and resolve cycle!
 24  */
 25 
 26 /**
 27  * reserve the root namespace
 28  */
 29 if ('undefined' != typeof OpenAjax && ('undefined' == typeof jsf || null == typeof jsf)) {
 30     OpenAjax.hub.registerLibrary("jsf", "www.sun.com", "1.0", null);
 31 }
 32 //just in case openajax has failed (testing environment)
 33 /**
 34 * @ignore
 35 */
 36 if (!window.jsf) {
 37 	/**
 38 	* @namespace jsf
 39 	*/
 40     var jsf = new function() {
 41         /*
 42          * Version of the implementation for the jsf.js.
 43          * <p />
 44          * as specified within the jsf specifications jsf.html:
 45          * <ul>
 46          * <li>left two digits major release number</li>
 47          * <li>middle two digits minor spec release number</li>
 48          * <li>right two digits bug release number</li>
 49          * </ul>
 50 		 * @constant
 51          */
 52         this.specversion = 220000;
 53         /**
 54          * Implementation version as specified within the jsf specification.
 55          * <p />
 56          * A number increased with every implementation version
 57          * and reset by moving to a new spec release number
 58          *
 59 		 * @constant
 60          */
 61         this.implversion = 0;
 62 
 63         /**
 64          * SeparatorChar as defined by UINamingContainer.getNamingContainerSeparatorChar()
 65          * @type {Char}
 66          */
 67         this.separatorchar = getSeparatorChar();
 68 
 69         /**
 70          * This method is responsible for the return of a given project stage as defined
 71          * by the jsf specification.
 72          * <p/>
 73          * Valid return values are:
 74          * <ul>
 75          *     <li>"Production"</li>
 76          *     <li>"Development"</li>
 77          *     <li>"SystemTest"</li>
 78          *     <li>"UnitTest"</li>
 79          * </li>
 80          *
 81          * @return {String} the current project state emitted by the server side method:
 82          * <i>javax.faces.application.Application.getProjectStage()</i>
 83          */
 84         this.getProjectStage = function() {
 85             var impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core.Impl);
 86             return impl.getProjectStage();
 87         };
 88 
 89         /**
 90          * collect and encode data for a given form element (must be of type form)
 91          * find the javax.faces.ViewState element and encode its value as well!
 92          * return a concatenated string of the encoded values!
 93          *
 94          * @throws an exception in case of the given element not being of type form!
 95          * https://issues.apache.org/jira/browse/MYFACES-2110
 96          */
 97         this.getViewState = function(formElement) {
 98             /*we are not allowed to add the impl on a global scope so we have to inline the code*/
 99             var impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core.Impl);
100             return impl.getViewState(formElement);
101         };
102 
103         /**
104          * returns the window identifier for the given node / window
105          * @param {optional String | DomNode}  the node for which the client identifier has to be determined
106          * @return the window identifier or null if none is found
107          */
108         this.getClientWindow = function() {
109             /*we are not allowed to add the impl on a global scope so we have to inline the code*/
110             var impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core.Impl);
111             return (arguments.length)? impl.getClientWindow(arguments[0]) : impl.getClientWindow();
112         }
113 
114         //private helper functions
115         function getSeparatorChar() {
116             var impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core.Impl);
117             return impl.getSeparatorChar();
118         }
119 
120     };
121 	//jsdoc helper to avoid warnings, we map later 
122 	window.jsf = jsf;
123 }
124 
125 /**
126  * just to make sure no questions arise, I simply prefer here a weak
127  * typeless comparison just in case some frameworks try to interfere
128  * by overriding null or fiddeling around with undefined or typeof in some ways
129  * it is safer in this case than the standard way of doing a strong comparison
130  **/
131 if (!jsf.ajax) {
132 	/**
133 	* @namespace jsf.ajax
134 	*/
135     jsf.ajax = new function() {
136 
137 
138         /**
139          * this function has to send the ajax requests
140          *
141          * following request conditions must be met:
142          * <ul>
143          *  <li> the request must be sent asynchronously! </li>
144          *  <li> the request must be a POST!!! request </li>
145          *  <li> the request url must be the form action attribute </li>
146          *  <li> all requests must be queued with a client side request queue to ensure the request ordering!</li>
147          * </ul>
148          *
149          * @param {String|Node} element: any dom element no matter being it html or jsf, from which the event is emitted
150          * @param {EVENT} event: any javascript event supported by that object
151          * @param {Map} options : map of options being pushed into the ajax cycle
152          */
153         this.request = function(element, event, options) {
154             if (!options) {
155                 options = {};
156             }
157             /*we are not allowed to add the impl on a global scope so we have to inline the code*/
158             var impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core.Impl);
159             return impl.request(element, event, options);
160         };
161 
162 		/**
163 		* Adds an error handler to our global error queue.
164 		* the error handler must be of the format <i>function errorListener(<errorData>)</i>
165 		* with errorData being of following format:
166 		* <ul>
167          *     <li> errorData.type : "error"</li>
168          *     <li> errorData.status : the error status message</li>
169          *     <li> errorData.serverErrorName : the server error name in case of a server error</li>
170          *     <li> errorData.serverErrorMessage : the server error message in case of a server error</li>
171          *     <li> errorData.source  : the issuing source element which triggered the request </li>
172          *     <li> eventData.responseCode: the response code (aka http request response code, 401 etc...) </li>
173          *     <li> eventData.responseText: the request response text </li>
174          *     <li> eventData.responseXML: the request response xml </li>
175         * </ul>
176          *
177          * @param {function} errorListener error handler must be of the format <i>function errorListener(<errorData>)</i>
178 		*/
179         this.addOnError = function(/*function*/errorListener) {
180             var impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core.Impl);
181             return impl.addOnError(errorListener);
182         };
183 
184         /**
185          * Adds a global event listener to the ajax event queue. The event listener must be a function
186          * of following format: <i>function eventListener(<eventData>)</i>
187          *
188          * @param {function} eventListener event must be of the format <i>function eventListener(<eventData>)</i>
189          */
190         this.addOnEvent = function(/*function*/eventListener) {
191             var impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core.Impl);
192             return impl.addOnEvent(eventListener);
193         };
194 
195         /**
196          * processes the ajax response if the ajax request completes successfully
197          * @param request the ajax request!
198          * @param context the ajax context!
199          */
200         this.response = function(/*xhr request object*/request, context) {
201             var impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core.Impl);
202             return impl.response(request, context);
203         };
204     }
205 }
206 
207 if (!jsf.util) {
208 	/**
209 	* @namespace jsf.util
210 	*/
211     jsf.util = new function() {
212 
213         /**
214          * varargs function which executes a chain of code (functions or any other code)
215          *
216          * if any of the code returns false, the execution
217          * is terminated prematurely skipping the rest of the code!
218          *
219          * @param {DomNode} source, the callee object
220          * @param {Event} event, the event object of the callee event triggering this function
221          * @param {optional} functions to be chained, if any of those return false the chain is broken
222          */
223         this.chain = function(source, event) {
224             var impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core.Impl);
225             return impl.chain.apply(impl, arguments);
226         };
227     }
228 }
229 
230 
231