1 /* Licensed to the Apache Software Foundation (ASF) under one or more
  2  * contributor license agreements.  See the NOTICE file distributed with
  3  * this work for additional information regarding copyright ownership.
  4  * The ASF licenses this file to you under the Apache License, Version 2.0
  5  * (the "License"); you may not use this file except in compliance with
  6  * the License.  You may obtain a copy of the License at
  7  *
  8  *      http://www.apache.org/licenses/LICENSE-2.0
  9  *
 10  * Unless required by applicable law or agreed to in writing, software
 11  * distributed under the License is distributed on an "AS IS" BASIS,
 12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  * See the License for the specific language governing permissions and
 14  * limitations under the License.
 15  */
 16 /**
 17  * @class
 18  * @name _AjaxUtils
 19  * @memberOf myfaces._impl.xhrCore
 20  * @description
 21  *
 22  * A set of helper routines which are utilized within our Ajax subsystem and nowhere else
 23  *
 24  * TODO move this into a singleton, the current structure is
 25  * still a j4fry legacy we need to get rid of it in the long run
 26  */
 27 _MF_SINGLTN(_PFX_XHR+"_AjaxUtils", _MF_OBJECT,
 28 /** @lends myfaces._impl.xhrCore._AjaxUtils.prototype */
 29 {
 30 
 31 
 32     /**
 33      * determines fields to submit
 34      * @param {Object} targetBuf - the target form buffer receiving the data
 35      * @param {Node} parentItem - form element item is nested in
 36      * @param {Array} partialIds - ids fo PPS
 37      */
 38     encodeSubmittableFields : function(targetBuf,
 39                                        parentItem, partialIds) {
 40 
 41         //try {
 42             if (!parentItem) throw "NO_PARITEM";
 43 
 44 
 45             if (partialIds ) {
 46                 this.encodePartialSubmit(parentItem, false, partialIds, targetBuf);
 47             } else {
 48                 // add all nodes
 49                 var eLen = parentItem.elements.length;
 50                 for (var e = 0; e < eLen; e++) {
 51                     this.encodeElement(parentItem.elements[e], targetBuf);
 52                 } // end of for (formElements)
 53             }
 54 
 55         //} catch (e) {
 56         //    context._mfInternal._onException(request, context, "myfaces._impl.xhrCore._AjaxUtils", "encodeSubmittableFields", e);
 57         //}
 58     },
 59 
 60      /**
 61      * appends the issuing item if not given already
 62      * @param item
 63      * @param targetBuf
 64      */
 65     appendIssuingItem: function (item, targetBuf) {
 66         // if triggered by a Button send it along
 67         if (item && item.type && item.type.toLowerCase() == "submit") {
 68             targetBuf.append(item.name, item.value);
 69         }
 70     },
 71 
 72 
 73     /**
 74      * encodes a single input element for submission
 75      *
 76      * @param {Node} element - to be encoded
 77      * @param {} targetBuf - a target array buffer receiving the encoded strings
 78      */
 79     encodeElement : function(element, targetBuf) {
 80 
 81         //browser behavior no element name no encoding (normal submit fails in that case)
 82         //https://issues.apache.org/jira/browse/MYFACES-2847
 83         if (!element.name) {
 84             return;
 85         }
 86 
 87         var _RT = this._RT;
 88         var name = element.name;
 89         var tagName = element.tagName.toLowerCase();
 90         var elemType = element.type;
 91         if (elemType != null) {
 92             elemType = elemType.toLowerCase();
 93         }
 94 
 95         // routine for all elements
 96         // rules:
 97         // - process only inputs, textareas and selects
 98         // - elements muest have attribute "name"
 99         // - elements must not be disabled
100         if (((tagName == "input" || tagName == "textarea" || tagName == "select") &&
101                 (name != null && name != "")) && !element.disabled) {
102 
103             // routine for select elements
104             // rules:
105             // - if select-one and value-Attribute exist => "name=value"
106             // (also if value empty => "name=")
107             // - if select-one and value-Attribute don't exist =>
108             // "name=DisplayValue"
109             // - if select multi and multple selected => "name=value1&name=value2"
110             // - if select and selectedIndex=-1 don't submit
111             if (tagName == "select") {
112                 // selectedIndex must be >= 0 sein to be submittet
113                 if (element.selectedIndex >= 0) {
114                     var uLen = element.options.length;
115                     for (var u = 0; u < uLen; u++) {
116                         // find all selected options
117                         //var subBuf = [];
118                         if (element.options[u].selected) {
119                             var elementOption = element.options[u];
120                             targetBuf.append(name, (elementOption.getAttribute("value") != null) ?
121                                     elementOption.value : elementOption.text);
122                         }
123                     }
124                 }
125             }
126 
127             // routine for remaining elements
128             // rules:
129             // - don't submit no selects (processed above), buttons, reset buttons, submit buttons,
130             // - submit checkboxes and radio inputs only if checked
131             if ((tagName != "select" && elemType != "button"
132                     && elemType != "reset" && elemType != "submit" && elemType != "image")
133                     && ((elemType != "checkbox" && elemType != "radio") || element.checked)) {
134                 if ('undefined' != typeof element.files && element.files != null && _RT.getXHRLvl() >= 2 && element.files.length) {
135                     //xhr level2
136                     targetBuf.append(name, element.files[0]);
137                 } else {
138                     targetBuf.append(name, element.value);
139                 }
140             }
141 
142         }
143     }
144 });