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             if (!parentItem) throw "NO_PARITEM";
 41             if (partialIds ) {
 42                 this.encodePartialSubmit(parentItem, false, partialIds, targetBuf);
 43             } else {
 44                 // add all nodes
 45                 var eLen = parentItem.elements.length;
 46                 for (var e = 0; e < eLen; e++) {
 47                     this.encodeElement(parentItem.elements[e], targetBuf);
 48                 } // end of for (formElements)
 49             }
 50 
 51     },
 52 
 53      /**
 54      * appends the issuing item if not given already
 55      * @param item
 56      * @param targetBuf
 57      */
 58     appendIssuingItem: function (item, targetBuf) {
 59         // if triggered by a Button send it along
 60         var identifier = item.id || item.name;
 61         var type = ((item && item.type) || "").toLowerCase();
 62 
 63         if(targetBuf.hasKey(identifier)) { //already processed within the values
 64             return;
 65         }
 66 
 67         //MYFACES-4606 we cannot send a value on an unchecked box as issuing element
 68         var isCheckboxRadio = "checkbox" == type || "radio" == type;
 69         if(isCheckboxRadio && !item.checked) {
 70            return;
 71         } else if (isCheckboxRadio) {
 72            var value = ("undefined" == typeof item.value || null == item.value) ? true : item.value;
 73            targetBuf.append(identifier, value);
 74            //item must have a valid value to be able to be appended, without it no dice!
 75         } else if(!(("undefined" == typeof item.value) || (null == item.value))) {
 76             var itemValue = item.value;
 77             targetBuf.append(identifier, itemValue);
 78         }
 79     },
 80 
 81 
 82     /**
 83      * encodes a single input element for submission
 84      *
 85      * @param {Node} element - to be encoded
 86      * @param {} targetBuf - a target array buffer receiving the encoded strings
 87      */
 88     encodeElement : function(element, targetBuf) {
 89 
 90         //browser behavior no element name no encoding (normal submit fails in that case)
 91         //https://issues.apache.org/jira/browse/MYFACES-2847
 92         if (!element.name) {
 93             return;
 94         }
 95 
 96         var _RT = this._RT;
 97         var name = element.name;
 98         var tagName = element.tagName.toLowerCase();
 99         var elemType = element.type;
100         if (elemType != null) {
101             elemType = elemType.toLowerCase();
102         }
103 
104         // routine for all elements
105         // rules:
106         // - process only inputs, textareas and selects
107         // - elements muest have attribute "name"
108         // - elements must not be disabled
109         if (((tagName == "input" || tagName == "textarea" || tagName == "select") &&
110                 (name != null && name != "")) && !element.disabled) {
111 
112             // routine for select elements
113             // rules:
114             // - if select-one and value-Attribute exist => "name=value"
115             // (also if value empty => "name=")
116             // - if select-one and value-Attribute don't exist =>
117             // "name=DisplayValue"
118             // - if select multi and multple selected => "name=value1&name=value2"
119             // - if select and selectedIndex=-1 don't submit
120             if (tagName == "select") {
121                 // selectedIndex must be >= 0 sein to be submittet
122                 if (element.selectedIndex >= 0) {
123                     var uLen = element.options.length;
124                     for (var u = 0; u < uLen; u++) {
125                         // find all selected options
126                         //var subBuf = [];
127                         if (element.options[u].selected) {
128                             var elementOption = element.options[u];
129                             targetBuf.append(name, (elementOption.getAttribute("value") != null) ?
130                                     elementOption.value : elementOption.text);
131                         }
132                     }
133                 }
134             }
135 
136             // routine for remaining elements
137             // rules:
138             // - don't submit no selects (processed above), buttons, reset buttons, submit buttons,
139             // - submit checkboxes and radio inputs only if checked
140             if ((tagName != "select" && elemType != "button"
141                     && elemType != "reset" && elemType != "submit" && elemType != "image")
142                     && ((elemType != "checkbox" && elemType != "radio") || element.checked)) {
143                 if ('undefined' != typeof element.files && element.files != null && _RT.getXHRLvl() >= 2 && element.files.length) {
144                     //xhr level2
145                     targetBuf.append(name, element.files[0]);
146                 } else {
147                     targetBuf.append(name, element.value);
148                 }
149             }
150 
151         }
152     }
153 });